dry-rb / dry-auto_inject Goto Github PK
View Code? Open in Web Editor NEWContainer-agnostic constructor injection mixin
Home Page: https://dry-rb.org/gems/dry-auto_inject/
License: MIT License
Container-agnostic constructor injection mixin
Home Page: https://dry-rb.org/gems/dry-auto_inject/
License: MIT License
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
.
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?
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.
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
Hi,
I am not sure where to ask:
Here is my question ๐ : https://discuss.dry-rb.org/t/examples-of-how-to-use-dry-container-dry-auto-inject/82?u=jmgarnier
Thanks for the libraries & blog posts anyway ๐ I can't wait before trying dry-transactions
and dry-monad
!
Hi guys,
I was playing around with this library and the related ones and I came up with this line of code: https://github.com/dry-rb/dry-auto_inject/blob/master/lib/dry/auto_inject.rb#L44
Can someone please explain me how this is possible? Since AutoInject::Builder
is a class and not a module.
Thank you in advance.
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
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.
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.
The test I have added in #81 will fail without the corresponding update to the implementation.
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).
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
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?
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.
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.
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?
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?
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?
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.
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.
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.
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
This will help reduce surprise when people pass unknown args and don't see an expected error.
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.
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)>
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
The Hanami Action should be instantiated properly.
ruby:3.0.3-slim-buster
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.
Use the code above using rails 7.1
Can inject the service
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')
We have a bunch of nice features that are completely undocumented :(
kwargs
strategy*args
strategyRight 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.
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.
Right now they are broken due to rubinius/rubinius#3538. When this bug is fixed (a PR is underway at rubinius/rubinius#3650), we can ensure the tests all pass on rbx again and put it back in the matrix of required platforms on Travis.
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:
Dry::KeyInject
constructor DI using keyword argumentsDry::SetterInject
setter DI; allows to set visibility of readersDry::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 readersThe 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?
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!
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.
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>'
namespace :app do
task my_test_task: :environment do
Zeitwerk::Loader.eager_load_all
end
end
No error appears.
I find same error in other product dry-rb/dry-matcher#31 and this is solution dry-rb/dry-matcher#32
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.