dry-rb / dry-core Goto Github PK
View Code? Open in Web Editor NEWA toolset of small support modules used throughout the @dry-rb & @rom-rb ecosystems
Home Page: https://dry-rb.org/gems/dry-core/
License: MIT License
A toolset of small support modules used throughout the @dry-rb & @rom-rb ecosystems
Home Page: https://dry-rb.org/gems/dry-core/
License: MIT License
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
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
).
No errors here :)
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin20]
2.3.23
0.9.0
PR with fix this issue: #72
I'm adding Skylight.io to a Hanami app. It uses stuff from ActiveSupport, but they avoid using Core Extensions (monkey patches). So, ActiveSupport is available, but the Inflector isn't used for the normal application. (It is used for their CLI, but that's not being loaded here.)
The trouble is that, when Hanami uses a repository, it calls Dry::Core::Inflector.camelize(name)
through ROM.
By itself, this should be fine, but Dry::Core::Inflector
attempts to load 3 different back-end engines, in this order: ActiveSupport::Inflector
, Dry::Inflector
, Inflecto
.
It first tries to require ActiveSupport::Inflector
, which in this case succeeds, since activesupport
is loaded. But, I don't actually want to load that :)
One way I was able to fix this was to change the order so dry-inflector
is first, and add that to my Gemfile
. This solves my problem, but I don't think we should be loading ActiveSupport::Inflector
automatically. Some people use ActiveSupport
without monkey patching, and we should encourage that. Maybe we could leverage it if it's already loaded, but not require it automatically here?
Related:
skylightio/skylight-ruby#121 I originally thought this was a bug in skylight-ruby
, but it's a bug in dry-core
.
Happy to open a PR for this, just want to get everyone's thoughts before I move forward. I know this is an issue with ROM 3, since ROM 4 uses rom-support
's Inflector
, which is actually the apparent predecessor to the dry-core
version I'm talking about now.
Release 0.9.0 is broken. Because of the removal of the Constants
:
v0.8.1...v0.9.0#diff-96814e9c79807ef64d126407350ffd3011e57aa5406c0625219fda5c6b1c8774L12
Causes error:
/usr/local/bundle/gems/dry-core-0.9.0/lib/dry/core/class_attributes.rb:65:in `defines': uninitialized constant Dry::Core::ClassAttributes::IDENTITY (NameError)
Because of the reference to the constant here:
v0.8.1...v0.9.0#diff-96814e9c79807ef64d126407350ffd3011e57aa5406c0625219fda5c6b1c8774R65
References
https://github.com/dry-rb/dry-core/blob/v0.9.0/lib/dry/core/constants.rb#L30
Not to get an unexpected constant missing error
So, we use common constants extensively in many projects, it'd be reasonable to gather them here. I'm talking about stuff like EMPTY_HASH
, EMPTY_ARRAY
or more "exotic" like Undefined
etc.
https://www.reddit.com/r/ruby/comments/olksxg/optimizing_performance_in_memowise_a_new/h5fex06/?context=3
panorama-ed/memo_wise#189
I suppose we can steal something from memo_wise and make memoization faster (hey, they have the same license).
I'm planning to read their code and probably make a PR or two here, but time is scarce these days, so not sure when/if it will happen 😿
Clone PR above, run benchmarks.
dry-core is faster, of course.
An added deprecation warning in dry-types v0.12.0 caused a breakage in scale-factory/aws-assume-role. It has a subcommand aws-assume-role environment
where it sets environment variables by writing sourcable bash to $stdout (similar to rbenv init -
); but the deprecation warnings emitted by dry-types caused the output to get mangled. Writing to $stderr would have ensured that the warnings were still printed but not would not have broken the aws-assume-role environment
command.
scalefactory/aws-assume-rule#15 documents some of the background.
After upgrade to latest gems (zeitwerk release), I'm getting in the Rails app when trying to run tests:
/home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/dry-core-0.9.0/lib/dry/core/deprecations.rb:227:in `block (2 levels) in deprecate_constant': uninitialized constant Dry::Struct::Extensions (NameError)
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader/helpers.rb:127:in `const_get'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader/helpers.rb:127:in `cget'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader.rb:246:in `block (2 levels) in eager_load'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader/helpers.rb:41:in `block in ls'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader/helpers.rb:27:in `each'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader/helpers.rb:27:in `ls'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader.rb:234:in `block in eager_load'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader.rb:219:in `synchronize'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader.rb:219:in `eager_load'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader.rb:318:in `each'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/loader.rb:318:in `eager_load_all'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/application/finisher.rb:74:in `block in <module:Finisher>'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/initializable.rb:32:in `instance_exec'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/initializable.rb:32:in `run'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/initializable.rb:61:in `block in run_initializers'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:228:in `block in tsort_each'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:431:in `each_strongly_connected_component_from'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:349:in `block in each_strongly_connected_component'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:347:in `each'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:347:in `call'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:347:in `each_strongly_connected_component'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:226:in `tsort_each'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/tsort.rb:205:in `tsort_each'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/initializable.rb:60:in `run_initializers'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/application.rb:372:in `initialize!'
from /home/wojtek/Projects/tiramizoo/dm/config/environment.rb:5:in `<top (required)>'
from /home/wojtek/Projects/tiramizoo/dm/test/test_helper.rb:2:in `require_relative'
from /home/wojtek/Projects/tiramizoo/dm/test/test_helper.rb:2:in `<top (required)>'
from /home/wojtek/Projects/tiramizoo/dm/test/controllers/healths_controller_test.rb:1:in `require'
from /home/wojtek/Projects/tiramizoo/dm/test/controllers/healths_controller_test.rb:1:in `<top (required)>'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/test_unit/runner.rb:47:in `require'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/test_unit/runner.rb:47:in `block in load_tests'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/test_unit/runner.rb:47:in `each'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/test_unit/runner.rb:47:in `load_tests'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/test_unit/runner.rb:40:in `run'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/commands/test/test_command.rb:33:in `perform'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/command/base.rb:87:in `perform'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/command.rb:48:in `invoke'
from /home/wojtek/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/commands.rb:18:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
This happens when config.eager_load = true
in the config/environments/test.rb (when it's false it works fine)
I'm not using Dry::Struct::Extensions
anywhere directly.
I'm using only basic Dry::Validation::Contract
and Dry::Struct
Version 1.0.1 removes support for Ruby 2.7. This is a breaking change that affects anyone running Ruby v2.7 and has this listed as a dependency.
N/A
The removal of support for a Ruby version should be done as a major version change. This would avoid inadvertent breaking changes when making patch updates.
Hello! I'm writing on behalf of the team behind MemoWise
, a Ruby memoization gem that aims to provide fast memoized lookups. First of all, I wanted to say we're big fans of Dry::Core::Memoizable
—had we known about it years ago we might not have ever written our gem and instead just used yours. 😄
In a recent push to increase performance, we took inspiration from Dry::Core::Memoizable
and used Array#hash
directly to produce our hash keys, rather than using array keys (which the hash has to compare using both Array#hash
and a more expensive Array#eql?
call). This is a really clever solution @flash-gordon came up with, and it made our gem much faster.
However, after discussions among our team we've decided we don't feel comfortable with this approach because of its risk of hash collisions: two different sets of method arguments could hash to the same integer, and our gem would return incorrect memoized results. While unlikely, collisions are not impossible (which is why hashes use both #hash
and #eql?
when comparing keys). This behavior would also be nondeterministic and hard for users to debug because Ruby uses pseudorandom hash functions so collisions will vary between different runs of the Ruby interpreter.
We haven't noticed any hash collisions ourselves, but because the bug would be subtle we can't be confident it hasn't already happened to us, and for the time being we do not consider this optimization safe. We wanted to let you know we plan to update MemoWise
to use array hash keys again instead of directly calling .hash
to produce integer keys, and give you the opportunity to similarly update Dry::Core::Memoizable
if you agree with our conclusion. Please let us know what you decide to do! If you decide to remove Array#hash
, we'll update our benchmarks to compare against the latest version of Dry::Core::Memoizable
. If you decide not to, that's okay too—we'll just link to this issue explaining the differences between our gems.
Hello! I'm trying to define a simple DSL using ClassAttributes from dry-core but encountered a weird issue in the process. Please have in mind topic of instance/class variables, inheritance and all the hassles related to that are a bit challenging to me so please forgive my ignorance if I'm asking for something obvious :) I'm also not entirely sure it is a bug or just me misusing the ClassAccessor but i was asked to port that question here from Zulip so let's find out.
class Base
extend Dry::Core::ClassAttributes
defines :exception_handlers
def self.handle_exception(key, value)
new_exception_handlers = exception_handlers || {}
new_exception_handlers[key] = value
exception_handlers new_exception_handlers
end
handle_exception :no_method_error, :default
end
class ClassA < Base
handle_exception :no_method_error, :class_a_overwrite
end
class ClassB < Base
end
pp Base.exception_handlers
# => {:no_method_error=>:class_a_overwrite}
pp ClassB.exception_handlers
# => {:no_method_error=>:class_a_overwrite}
pp Base.exception_handlers
# => {:no_method_error=>:default}
pp ClassA.exception_handlers
# => {:no_method_error=>:class_a_overwrite}
pp ClassB.exception_handlers
# => {:no_method_error=>:default}
This wasn't an issue in 0.5.0, but when we upgraded to 0.6.0 we started getting lots of warnings from using #memoize
on methods that take no args:
warning: Skipping set of ruby2_keywords flag for foo (method accepts keywords or method does not accept argument splat)
Provide detailed steps to reproduce, an executable script would be best.
pry(main)> class MyClass
pry(main)* include Dry::Core::Memoizable
pry(main)* def foo; end
pry(main)* memoize(:foo)
pry(main)* end
/home/rando/.gem/ruby/2.7.3/gems/dry-core-0.6.0/lib/dry/core/memoizable.rb:78: warning: Skipping set of ruby2_keywords flag for foo (method accepts keywords or method does not accept argument splat)
=> MyClass
No warnings emitted.
When we upgraded from dry-core 0.7.1 to 0.8.0, some tests in our test suite started failing. I think this commit (d2a8d24) changes what memoized value gets returned when a subclass inherits from a class where the memoization was defined.
require "dry/core/memoizable"
class Base
include Dry::Core::Memoizable
def all
[:base]
end
def page
all + [:page]
end
memoize :all, :page
end
class Child < Base
def all
super + [:search]
end
end
child = Child.new
pp all: child.all, page: child.page
__END__
Dry::Core 0.7.1
{:all=>[:base, :search],
:page=>[:base, :search, :page]}
Dry::Core 0.8.0
{:all=>[:base, :search],
:page=>[:base, :page]}
# Missing :search
In our app, this is chaining ActiveRecord Relation objects, in this test case I've simulated it with an Array.
In dry-core 0.7.1, the #page
method on Child uses its own memoized #all
method, but in 0.8.0 it seems to have used Base#all
instead, so its missing the :search
it added.
The dry-logger raises an exception while trying to warn about something
class TestLogger
extend Dry::Initializer
option :array, Types::Strict::Array.default([])
end
in this example Logger should inform about freezing the default value
The problem could be solved if we update the Logger.new
in this line
from Logger.new(output)
to Logger.new(stream: output)
Warning should be visible in the log and no exception should be raised
Pretty much subj:
/home/ixti/.gem/ruby/2.3.3/gems/dry-validation-0.10.3/lib/dry/validation/message_compiler.rb:13: warning: already initialized constant Dry::Validation::MessageCompiler::EMPTY_OPTS
/home/ixti/.gem/ruby/2.3.3/gems/dry-core-0.2.1/lib/dry/core/constants.rb:52: warning: previous definition of EMPTY_OPTS was here
Not a greatest issue, but still would be nice to get rid of those ;))
Hello!
I have a Rails application which has some unusual behaviour when paired with dry-core.
Here's the branch that replicates the issue. If you clone down this app with this branch and run:
bundle install
DISABLE_SPRING=1 rails runner projects.rb
Then you will see the issue that I am facing. It's a two-parter:
repo.all.first
should be a Projects::Project
, and it is... but it's seemingly coming from Dry::Core::ClassBuilder
, rather than the one defined in the application.to_model
call, but it doesn't. This call should be inherited from ApplicationModel
, by way of the Projects::Project
class within the application.So in effect, both of the last statements in projects.rb
should return true
if this code is working as it should.
To attempt to work around this, I've tried doing require "projects/project"
in project_repository.rb
, but this flips it around:
to_model
call.The source of this problem appears to be this code within ClassBuilder
:
dry-core/lib/dry/core/class_builder.rb
Lines 69 to 77 in 3b26625
In particular:
dry-core/lib/dry/core/class_builder.rb
Line 73 in 3b26625
If I remove the if
statement from this line and manually require the projects/project
file in my ProjectRepository
class, everything works correctly, at least in my application.
That line -- in its entirety -- was added in abdb106, but the reasoning for this is opaque to me. Seems to be fixing / working around some sort of Ruby bug that only existed pre-Ruby 2.4? Well, my app is using Ruby 2.5 so this line doesn't do anything.
I'm betting this is going to be down to some weird combination between dry-core and Rails' own auto-loading mumbo-jumbo. I'd just like to get an expert opinion before I go blaming Rails (again).
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.