dry-rb / dry-core

A toolset of small support modules used throughout the @dry-rb & @rom-rb ecosystems
https://dry-rb.org/gems/dry-core/
MIT License
171 stars 34 forks source link

[BUG] Uninitialized constant error for IDENTITY/Undefined #73

Closed bestwebua closed 2 years ago

bestwebua commented 2 years ago

Describe the bug

Uninitialized constant error for IDENTITY/Undefined due using short namespaces.

NameError:
  uninitialized constant Dry::Core::ClassAttributes::IDENTITY
        def defines(*args, type: ::Object, coerce: IDENTITY) # rubocop:disable Metrics/PerceivedComplexity

To Reproduce

This issue appear in my project after dry-system version has been bumped from 0.25.0 to 0.26.0 (dry-core has been bumped from 0.8.1 to 0.9.0).

Expected behavior

No errors here :)

My environment

PR

PR with fix this issue: https://github.com/dry-rb/dry-core/pull/72

solnic commented 2 years ago

Hey thanks for the report. Could you upgrade to dry-system 0.27.0 and see if this goes away?

bestwebua commented 2 years ago

Hey thanks for the report. Could you upgrade to dry-system 0.27.0 and see if this goes away?

@solnic Yup. After update I see another error:

NameError:
  uninitialized constant Dry::System::Plugins
        extend Dry::System::Plugins
marian13 commented 2 years ago

Describe the bug

Uninitialized constant error for IDENTITY/Undefined due using short namespaces.

NameError:
  uninitialized constant Dry::Core::ClassAttributes::IDENTITY
        def defines(*args, type: ::Object, coerce: IDENTITY) # rubocop:disable Metrics/PerceivedComplexity

To Reproduce

This issue appear in my project after dry-system version has been bumped from 0.25.0 to 0.26.0 (dry-core has been bumped from 0.8.1 to 0.9.0).

Expected behavior

No errors here :)

My environment

  • Affects my production application: YES
  • Ruby version: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin20]
  • Bundler version: 2.3.23
  • dry-core version: 0.9.0

PR

PR with fix this issue: #72

I am experiencing this error as well, but with dry-validation 😅

Screenshot 2022-10-15 at 19 03 59
bestwebua commented 2 years ago

@marian13 With full namespaces it works like a charm with next dry stack:

gem 'dry-system', '~> 0.26.0'
gem 'dry-transaction', '0.13.3'
gem 'dry-transformer', '~> 0.1.1'
gem 'dry-validation', '~> 1.9'
solnic commented 2 years ago

How can I reproduce this? I tried this and it worked:

➜  ~ gem i dry-system
Fetching dry-system-0.27.1.gem
Successfully installed dry-system-0.27.1
1 gem installed

➜  ~ irb
irb(main):001:0> require 'dry-system'
=> true

➜  ~ gem i dry-validation
Successfully installed dry-validation-1.9.0
1 gem installed

➜  ~ irb
irb(main):001:0> require 'dry-validation'
=> true
solnic commented 2 years ago

@flash-gordon I believe we need to have require "dry/core/constants" in all places that refer to constants, they are not auto-loadable after all. WDYT?

bestwebua commented 2 years ago

@solnic Here is the place where app crushes:

require 'bundler'
require 'dotenv'
require_relative './environment'

Dotenv.load('.env', ".env.#{System::Environment.current_env}")

require 'dry/system/container' # place where raised an error
require 'zeitwerk'

module System
  class Container < Dry::System::Container
    use :env, inferrer: -> { System::Environment.current_env.to_sym }
    use :zeitwerk

    configure do |config|
      config.component_dirs.add('app') do |dir|
        dir.instance = proc do |component|
          component_type = ->(type) { component.identifier.include?(type) }
          component.loader.constant(component) if %w[jobs mailers serializers].any?(&component_type)
        end
      end

      config.component_dirs.add('lib') do |dir|
        dir.instance = proc do |component|
          component.loader.constant(component) if component.identifier.include?('services')
        end
      end
    end
  end

  Import = System::Container.injector
end

After bumping dry-system to 0.27.0 raised another error:

Failure/Error: require_relative '../system/container'

NameError:
  uninitialized constant Dry::System::Plugins

        extend Dry::System::Plugins
                          ^^^^^^^^^
# ./system/container.rb:9:in `<top (required)>'
# ./spec/spec_helper.rb:7:in `require_relative'
# ./spec/spec_helper.rb:7:in `<top (required)>'
# ------------------
# --- Caused by: ---
# LoadError:
#   cannot load such file -- dry/system/container
#   ./system/container.rb:9:in `<top (required)>'

As I understend my propose with fix is wrong, right?

solnic commented 2 years ago

You need to do require "dry/system" and it should work. This file sets up zeitwerk and the rest will autoload.

bestwebua commented 2 years ago

Yup. It's works, thanks:

require 'dry/system/container' -> require 'dry/system'

And sorry for mess.

solnic commented 2 years ago

@bestwebua I'm glad that it works and no worries. This was a helpful report. I should add more info to the dry-system release notes.