Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
Stergio
@stergiom
:beers: @flash-gordon, that does seem to work
Armin Pašalić
@Krule
Hi everyone, in dry-validation I would like to do something like dry-rb/dry-validation#268
is this at all possible?
or is there an alternative approcah
Stergio
@stergiom
class TheClass < SomeOtherClass
    def initialize(some_dep:)
        super()
        @some_dep = some_dep
    end
end

Using auto_inject this becomes..

class TheClass < SomeOtherClass
    include Inject[:some_dep]

    def initialize(*)
        super
    end
end

The initial example calls super with no arguments, with auto_inject in the mix does the parent class receive arugments?

Nikita Shilnikov
@flash-gordon
@stergiom yes, the gem does its best to match the parent's arguments, but this is not always possible IIRC
Stergio
@stergiom
@flash-gordon, so would passing a specific parameter to a parent like this suffice?
class TheClass < SomeOtherClass
    include Inject[:some_dep]

    def initialize(*)
        super(only_for_parent)
    end
end
Nikita Shilnikov
@flash-gordon
I'd expect something like this to work
class TheClass < SomeOtherClass
  include Inject[:some_dep]

  def initialize(**kwargs)
    super(only_for_parent, kwargs)
  end
end
Stergio
@stergiom
:100: I’ll give it some playtime..
thanks
Stergio
@stergiom
I have a few classes using auto_inject for dependencies in the same container and have to keep track of the order they get require'd and register'd, is there a way to get dynamic component resolution with dry-container short of using dry-system?
Nikita Shilnikov
@flash-gordon
@stergiom well, you can just register them manually with a simple directory traverse and register(key) { require full_path; constantize(full_path).new }
Stergio
@stergiom
I went with something to that effect, the issue is that a.rb has a include Inject[:b] and when register(:a, A.new) happens it's expecting that :b has already been instantiated in the container..
Tim Riley
@timriley
@stergiom what you want instead is to register a block that returns your object:
register(:a) { A.new }
This means the instantiation is lazy, and this’ll allow both :a and :b to be registered before you resolve :a from the container the first time
Stergio
@stergiom
@timriley, is the instantiation still a singleton when used this way?
Tim Riley
@timriley
@stergiom they’re not singletons when used like that, no. Every time you resolve :a from the container it’ll be a new object.
I think dry-container might have an option for that though… /me looks
Nope, I was wrong.
you could probably write a dry-container resolver that’ll resolve from the block once and then return that original object in subsequent times
Stergio
@stergiom
:beers: might actually give that a shot
Tim Riley
@timriley
Cool, let us know how it goes!
I’d be interested to see it.
Tsehau Chao
@jodeci

Hiya, just starting with dry-validation here. I’m using custom error messages with i18n:

configure do
    config.messages_file = "config/locales/errors.zh-TW.yml"
    config.messages = :i18n
end

Not sure if this is intended, but by doing so, I get Dry::Validation::MissingMessageError for the built-in predicates (e.g. int?). Makes sense in a way, since I only have my custom messages in that yml, but OTOH it’s also fair to assume that the i18n lookup should fall back to the built-in messages?

Anyway my actual question is, so I have a fully translated errors.zh-TW.yml ready to share but where should I push to :D

Stergio
@stergiom

@timriley, I ended up recursing till everything resolved (or something could not)..

class Registration
  extend Dry::Monads::Try::Mixin

  def self.auto_resolve(container, namespace, class_list = nil, precedent = [])
    class_list ||= namespace.constants.map(&:to_s)

    cycle = class_list.select do |n|
      Try(Dry::Container::Error) { container.register(n.snake_case, namespace.const_get(n).new) }.failure?
    end

    return if cycle.empty?
    raise(Dry::Container::Error, "Unresolvable: #{cycle}") if (cycle <=> precedent).zero?

    send(__method__, container, namespace, cycle, class_list)
  end
end

Registration.auto_resolve(ServiceContainer, Services)
# -or-
Registration.auto_resolve(ServiceContainer, Services, Services.constants.select { .. })

might not be the optimal approach for dry-container but its doing okay for me right now, dynamic resolution for singletons would be a nice plus.

Michael Johnston
@lastobelus
in dry-validation, does anyone know of a way to make a high level rule use a predicate that depends on more than two values?
ie, this is fine:
```ruby
rule(whatever: [:foo, :bar, :quaz]) do | foo, bar, quaz|
foo.my_arity_2_predicate?(value(:bar))
end
rule(whatever: [:foo, :bar, :quaz]) do | foo, bar, quaz|
  foo.my_arity_2_predicate?(value(:bar))
end
but I can't find any way to do this:
rule(whatever: [:foo, :bar, :quaz]) do | foo, bar, quaz| foo.my_arity_3_predicate?(value(:bar), value(:quaz)) # predicate arity is invalid (ArgumentError) end
gah
rule(whatever: [:foo, :bar, :quaz]) do | foo, bar, quaz|
  foo.my_arity_3_predicate?(value(:bar), value(:quaz)) # predicate arity is invalid (ArgumentError)
end
Tim Riley
@timriley
@flash-gordon Thanks for taking care of that -auto_inject release, sorry I didn’t get to it sooner.
Nikita Shilnikov
@flash-gordon
@timriley sure, no worries man, btw I did that when I injected deps in my repos
Tim Riley
@timriley
oh? Mind if I see an example of what you’re doing?
Nikita Shilnikov
@flash-gordon
@timriley yeah, I added include AutoInject['time_machine'] where time_machine is a project-wide clock, then I call time_machine.now inside the repo rather than Time.now
Tim Riley
@timriley
Oh interesting. This is a rom-repo? How are you combining the time_machine dep with the rom dep that the repo needs?
Nikita Shilnikov
@flash-gordon
it just works :) I have a line like MyRepo.new(rom_container) in my app container, I still didn't bother with any smart registration so it works OOTB
Tim Riley
@timriley
Ah, I see!
I was trying to think about how that might work with the way we have repos configired atm:
module MyApp
  class Repository < ROM::Repository::Root
    include MyApp::Import.args["persistence.rom"]
  end
end
I guess we’d just confinue to use an args based constructor and throw the time_machine on that list
Nikita Shilnikov
@flash-gordon
for me it's not the case because I use same repos with different rom containers
Tim Riley
@timriley
oh!
Is this so you can work with different data sources or something?
Nikita Shilnikov
@flash-gordon
nope, two different containers with different connections, one has access to all data in the database and the other one is restricted with the client identifier, I called them public/private and use private exclusively for authentication
so technically it's the same database
Tim Riley
@timriley
Ah, that’s clever.
Stergio
@stergiom
class SomeClass
  include Inject[:some_dep]

  def initialize(diff_dep:)
    # do stuff with diff_dep and some_dep
  end
end
what should initialize look like to accept kwargs and auto_inject dependencies?