These are chat archives for dry-rb/chat

24th
Aug 2016
Michał Pietrus
@blelump
Aug 24 2016 10:35

hi @solnic, I am definietly not a reload–constant guru, but here's what I've found.

Having container without finalization indeed helps and this seems to be the best fit for the dev mode unless you want to explicitly desire some dependency, which hasn't been registered. Only dependencies that are auto–injected are getting registered by default. So if I expect a constant that is on container load path, but didn't get registrered into container, I may call AppContainer.auto_registrar.finalize!. This performs auto registration of all components I've specified in config.auto_register. So far so good, I have everything. Now I change something and it enters:

ActionDispatch::Reloader.to_prepare do
  Object.__send__(:remove_const, :Import)
  AppContainer.instance_variable_set('@_container', ::Concurrent::Hash.new)
  Import = AppContainer.injector
  AppContainer.auto_registrar.finalize!
end

It's not good approach since there're still references to the "old" constants and app crashes after refreshing it.

Besides the above issue, auto_registrar internally calls require_component of the container. The interesting part is Kernel.require which returns false for any n–th load (n > 1) so block doesn't get executed and the container is actually empty, however I am not sure that's the appropriate usage (calling auto_registrar.finalize!).

Igor
@svilenkov
Aug 24 2016 11:35
When using dry-initializer how can you add some code to the initialize() method without affecting gems behavior?
Piotr Solnica
@solnic
Aug 24 2016 11:55
@blelump I think you should talk to @timriley as I’m almost sure he’d be interested in seeing how hot-reloading of a container could be implemented properly. I won’t have time for this during this week. Way too much mojowork + dry-logic/validation. Sorry ¯_(⊙ʖ⊙)
for rails we probably need to integrate with their AS::Dependencies so it knows about constants loaded by the system
Andrew Kozin
@nepalez
Aug 24 2016 13:45
@keeperhood you can just reload the initializer
class MyClass
  extend Dry::Initializer::Mixin

  param :foo

  private

  def initialize(foo, bar)
    @bar = bar
    super(foo)
  end
end
Definitely you have to know a signature of the method to call super properly if you're going to change the signature
Michał Pietrus
@blelump
Aug 24 2016 14:08
@solnic , sure! Re AS::Dependencies, my thoughts was similar, however I'm already late due to various issues with hot reloading so I'm going to postpone this task for a while.
Igor
@svilenkov
Aug 24 2016 18:41
@nepalez I was thinking the same but what is the signature, it's defined by param values ?
Not sure if super without () would forward arguments if defined as *args
Igor
@svilenkov
Aug 24 2016 18:47
I think that will work actually
Just tried in irb
class MyClass
  extend Dry::Initializer::Mixin

  param :foo
  param :bar

  def initialize(*args)
    # do some custom initialization stuff here
    super # calling super without () will forward all arguments
  end
end
Andy Holland
@AMHOL
Aug 24 2016 19:25
@solnic is there anything in dry-v to pass through attributes that aren't defined in the validator and just apply validations for the ones that are, use-case being separation of schema/domain validation
Piotr Solnica
@solnic
Aug 24 2016 20:08
@AMHOL nope, it rejects unspeced keys
Andy Holland
@AMHOL
Aug 24 2016 20:09
Ahh OK, think supporting something like that could be beneficial?
I don't want to duplicate schema validations in domain validators
Andrew Kozin
@nepalez
Aug 24 2016 20:21

@keeperhood yes it would. My example displays that you principally can add new arguments of the initializer that does not defined by dry-initializer. But this time you should know what arguments to send to super explicitly.

What Dry::Initializer::Mixin does is provides a module with #initialize method defined, and then includes the module to the class. If you wish not to pollute your class scope with helpers (like param and option), you can make this inclusion explicitly:

class MyClass
  include Dry::Initializer.define -> do
    param :foo
    param :bar
  end
end

In any case what you get is the module with initialize method in a sequence of class ancestors. Then you can work with it via super in a common ruby way.

Piotr Solnica
@solnic
Aug 24 2016 21:20
@AMHOL not sure why would that be needed?
Andy Holland
@AMHOL
Aug 24 2016 21:28
You're right, was just getting mixed up thinking that if you didn't run predicates on the values it would fail
BTW for at the boundary schema validations do you think they should validate that values are filled and such, or just type validations?
I'm leaning towards just type validations
Piotr Solnica
@solnic
Aug 24 2016 21:59
@AMHOL yes at the boundary you simply needs coercions/type-checking but I haven't experimented with separating this yet
Andy Holland
@AMHOL
Aug 24 2016 22:00
Cool, give me a shout if you do :+1:
Piotr Solnica
@solnic
Aug 24 2016 22:00
my concern is duplication, not sure how to do it without duplication tbf
I duplicated the word duplication
Andy Holland
@AMHOL
Aug 24 2016 22:01
lol
Yeah same with me, but thinking about it more, I don't think it's an issue
Don Morrison
@elskwid
Aug 24 2016 22:01
duduplication
Andy Holland
@AMHOL
Aug 24 2016 22:06
i.e. schemas and validators should both work stand-alone, just that the validator would assume input of the correct type, but should still make assertions on required keys
i.e. with something like:
module Web
  module Blog
    module Schemas
      module Posts
        Update = Dry::Validation.Form do
          required(:id, :int).value(:int?)

          required(:post).schema do
            required(:title, :str).value(:str?)
            required(:content, :str).value(:str?)
          end
        end
      end
    end
  end
end

module Blog
  module Validators
    module Posts
      Update = Dry::Validation.Schema do
        required(:id)
        required(:title).filled(min_size?: 3)
        required(:content).filled(min_size?: 100)
      end
    end
  end
end
Although in the second case, messages doesn't report on the missing id
require 'dry-validation'

module Blog
  module Validators
    module Posts
      Update = Dry::Validation.Schema do
        required(:id)
      end
    end
  end
end

Blog::Validators::Posts::Update.({})
# => #<Dry::Validation::Result output={} messages={}>
Take it that's a bug?
Tim Riley
@timriley
Aug 24 2016 22:09
Or a not-yet-built-for use case, I think
There was some chat about it in here within the last couple of days IIRC
having a dry-v schema with a rule about the key but not the value
Andy Holland
@AMHOL
Aug 24 2016 22:10
Yeah, I would think it would assert that the key was present
Although in this case adding .filled is valid
Tim Riley
@timriley
Aug 24 2016 22:11
yeah, the problem is that rn I don’t think it does that
That's where the earlier discussion was
My uneasy feeling about the code you've posted is that I feel like I'd probably want my type specs to be inside my domain validation too
otherwise it feels... incomplete
Tim Riley
@timriley
Aug 24 2016 22:16
I would just want it to hard-fail if the type specs weren't met, instead of trying to coerce first, which is what you might do on the boundary schemas