These are chat archives for dry-rb/chat

4th
Apr 2016
John Backus
@backus
Apr 04 2016 00:09
@timriley @solnic In that case I would argue strongly that it should not be public API
I worry that I'll accidentally slip and do Types::Int instead of Types::Strict::Int (or coercible, etc) in some of my use cases. Easy to miss in review as well
It will likely be a common source of confusion / false positive bug reports
Russell Edens
@rx
Apr 04 2016 00:12
As a newbie to dry-types I had the same question and find it confusing.
Joe Van Dyk
@joevandyk
Apr 04 2016 02:18
Same here
Piotr Solnica
@solnic
Apr 04 2016 06:29
If we removed call from Definition then it would have to be treated in a special way in hash schemas and maybe other places too.
Piotr Solnica
@solnic
Apr 04 2016 06:37
Using constraints should be pretty cautions btw as it comes with a perf cost
Tim Riley
@timriley
Apr 04 2016 06:38
I think this is probably just an issue around not understanding what their purpose is.
Piotr Solnica
@solnic
Apr 04 2016 07:38
this is documented
We could do strict by default and move plain definitions to sth like Types::Def::Int
John Backus
@backus
Apr 04 2016 08:21
^ This would be better. Maybe even Types::Template::Int, Types::Internal::Int, or Types::Noop::Int
Piotr Solnica
@solnic
Apr 04 2016 08:27
my reasoning was that lack of any category means no behavior other than a definition
it’s probably a post-virtus expectation to have coercions enabled by default
which is a shame
Template looks weird tbh, Internal is not really true, it’s not internal, it’s public API, Noop looks weird too. But that’s just me :(
John Backus
@backus
Apr 04 2016 08:56
Heh yeah while they might not be 100% accurate to you it is probably best if they basically state "this is not useful" to the new user
Tim Riley
@timriley
Apr 04 2016 08:56
Yeah, it's more an Annotation
Piotr Solnica
@solnic
Apr 04 2016 08:57
this is useful as an annotation mechanism, Type::Definition also exposes meta API for setting arbitrary meta-data on types
we are going to use this extensively in rom very soon (schema branch was already merged in in rom-sql master, it uses type definitions from dry-types)
John Backus
@backus
Apr 04 2016 09:05

So the uses are

  1. annotations
  2. a base type with primitive and meta information which can be extended

am I missing something?

Piotr Solnica
@solnic
Apr 04 2016 09:05
nope, that’s it :)
@coop morning, shall we wrap up JSON branch in dry-v?
Piotr Solnica
@solnic
Apr 04 2016 09:10
@backus re mutant, I added mutant when working on 0.7 release. If that additional rspec config is needed for mutant, feel free just push it to master
I run mutant against specific method or a specific object, so I suppose I didn’t have any issues because of that
FYI <3
John Backus
@backus
Apr 04 2016 09:22
:smile:
re mutant: k I'll try to cleanup the snippet I shared and PR it. Just want to make sure it doesn't barf warnings about constants being redefined. Maybe also a check to make sure it is reloading everything in the registry
Piotr Solnica
@solnic
Apr 04 2016 09:26
btw IIRC dry-container now provides Container#keys so we don’t have to do _container.keys
Tim Cooper
@coop
Apr 04 2016 09:34
@solnic I have time now.
What do you need me to do?
Piotr Solnica
@solnic
Apr 04 2016 09:37
@coop point to dry-types master and see if CI is green? :D
Tim Cooper
@coop
Apr 04 2016 09:38
Well played.
I didn’t realise a release went out.
Let me have a look.
Piotr Solnica
@solnic
Apr 04 2016 09:38
oh it did not
but your dry-v branch points to your fork of dry-types
Tim Cooper
@coop
Apr 04 2016 09:38
Do you just want me to point to master?
Piotr Solnica
@solnic
Apr 04 2016 09:38
yes
Tim Cooper
@coop
Apr 04 2016 09:38
Cool.
Piotr Solnica
@solnic
Apr 04 2016 09:38
we’re gonna continue relying on master until we push new dry-types
Tim Cooper
@coop
Apr 04 2016 09:39
Makes sense.
Building now.
Piotr Solnica
@solnic
Apr 04 2016 09:43
just merge it in if it’s green
John Backus
@backus
Apr 04 2016 09:47
If you don't like Noop then maybe Abstract? Ruby convention would be Base but I kind of hate that
Hannes Nevalainen
@kwando
Apr 04 2016 10:00
dry-rb/dry-validation#91
Benjamin Klotz
@tak1n
Apr 04 2016 10:17

hey there, I just started with dry-validation for something work specific and got stuck on rules which depend on values from other rules

I got following schema:

SCHEMA = Dry::Validation.Schema do
          key(:type).required(:str?)
          key(:platform).required(:str?)

          key(:type) { inclusion?(['post', 'link', 'images', 'videos', 'comment']) }
          key(:platform) { inclusion?(['facebook', 'flickr', 'linkedin', 'twitter', 'xing', 'youtube']) }

          rule(content_presence: [:type, :content]) do |type, content|
            type.eql?('post').then(content.filled?)
          end
        end

The problem I have when passing in { type: 'post', platform: 'facebook' } its not complaining about the missing content.

Hannes Nevalainen
@kwando
Apr 04 2016 10:19
Just a guess, but you might need key(:content) rule
Benjamin Klotz
@tak1n
Apr 04 2016 10:22
added it but doesn't resolve the problem, hmm
Piotr Solnica
@solnic
Apr 04 2016 10:23
@tak1n you must specify all keys, it’s the best practice, schema should define everything, and domain rules should sit on top
Hannes Nevalainen
@kwando
Apr 04 2016 10:23
ok, then just sit tight for someone who knows this stuff better to arrive =)
like him ^^
Benjamin Klotz
@tak1n
Apr 04 2016 10:24
okay but I did that now
Dry::Validation.Schema do
   key(:type).required(:str?)
   key(:platform).required(:str?)
   key(:content)

    key(:type) { inclusion?(['post', 'link', 'images', 'videos', 'comment']) }
    key(:platform) { inclusion?(['facebook', 'flickr', 'linkedin', 'twitter', 'xing', 'youtube']) }

     rule(content_presence: [:type, :content]) do |type, content|
         type.eql?('post').then(content.filled?)
      end
 end
Hannes Nevalainen
@kwando
Apr 04 2016 10:25
I guess the type.eql?('post') is the culprit
Piotr Solnica
@solnic
Apr 04 2016 10:25
@tak1n key(:content).maybe(:str?)
key(:content) just expects the key to be there
Benjamin Klotz
@tak1n
Apr 04 2016 10:25
@solnic that solved it thx :)
Piotr Solnica
@solnic
Apr 04 2016 10:26
we could improve this btw, we could detect that rules are missing for a given value and let you know about it
Benjamin Klotz
@tak1n
Apr 04 2016 10:26
much to learn I have, young Padawan :D
Piotr Solnica
@solnic
Apr 04 2016 10:26
it’s my goal prior 1.0
Benjamin Klotz
@tak1n
Apr 04 2016 10:26
okay :)
Benjamin Klotz
@tak1n
Apr 04 2016 11:52

I now tried to get rid of that rule(content_presence) thing in favor of having smth like:

Dry::Validation.Schema do
  key(:type).required(:str?)
  key(:platform).required(:str?)

  key(:type) { inclusion?(['post', 'link', 'images', 'videos', 'comment']) }
  key(:platform) { inclusion?(['facebook', 'flickr', 'linkedin', 'twitter', 'xing', 'youtube']) }

  key(:type).required(:str?).when(:post?) do
    key(:content).required(:str?, :filled?)
  end

  key(:type).required(:str?).when(:link?) do
    key(:content).maybe(:str?)
    key(:link_url).required(:url?)
  end

  configure do
    def post?(value)
      value.eql?('post')
    end

    def link?(value)
      value.eql?('link')
    end

    def url?(value)
      value =~ /\A#{URI::regexp(['http', 'https'])}\z/
    end
  end
end

But it doesn't work and if it would work I'm unsure if I should do that or not :D
Basically I want to have different rules depending on the type passed in.

what exactly does not work is when passing in: { content: '', type: 'post', platform: 'facebook' }
but as far as I see I say key content is required and must be a string and must be filled in when type is post
Benjamin Klotz
@tak1n
Apr 04 2016 12:00
when commenting out the when(:link?) part it works with above mentioned input
not sure why when(:link?) would affect it when type is post :confused:
Piotr Solnica
@solnic
Apr 04 2016 12:14
Key is for defining structure unconditionally. This shouldn't even work and raise
Benjamin Klotz
@tak1n
Apr 04 2016 12:15
I thought that but wondered why it didn't raise xD
Should I open a ticket for that?
Piotr Solnica
@solnic
Apr 04 2016 12:15
You must define content key. And have a high lvl rule for it when it depends on other values
Yeah pls do. I consider this as a bug
Benjamin Klotz
@tak1n
Apr 04 2016 12:15
yep currently in looking how to do that with high level rules
Piotr Solnica
@solnic
Apr 04 2016 12:16
I will show you once I'm done with that duck I'm eating atm :laughing:
Benjamin Klotz
@tak1n
Apr 04 2016 12:16
tasty :P
thx
Benjamin Klotz
@tak1n
Apr 04 2016 12:42
I think the real problem I have here I kinda want to have a conditionally structure
I mean sure it is not a good idea to have a mutable structure depending on the type, but then again you could argue I'm not having a different structure its just that if the "user" of the higher level lib is not specifying that key it is allowed to be set to nil per default
Piotr Solnica
@solnic
Apr 04 2016 12:56
@tak1n you can just define this key to be optional
and use a custom type with a default value
Content = Strict::String.optional.default(nil)
then in schema optional(:content).maybe(Content)
this is how explicitness manifests itself in these libs, there are very little implicit behaviors, I know rubyists are used to it so there’s a learning curve here
Andy Holland
@AMHOL
Apr 04 2016 13:01
@solnic if it looks like a duck and it quacks like a duck...
Piotr Solnica
@solnic
Apr 04 2016 13:03
I had a duck for lunch, so there’s that
duck typing in the context of data is a mistake, people make their code more complicated because of that
duck typing in the context of objects that do stuff, yes please, but not when it comes to data, esp if it comes from a web form :)
Andy Holland
@AMHOL
Apr 04 2016 13:06
I was just gonna say don't eat it lol
Piotr Solnica
@solnic
Apr 04 2016 13:06
:D
Benjamin Klotz
@tak1n
Apr 04 2016 13:25
@solnic awesome exactly what I needed :D
yea its kinda mind bending at the beginning and seeming complex but I actually like it :D
can't explain why, its just a feeling xD
Piotr Solnica
@solnic
Apr 04 2016 13:27
you are used to stuff that you won’t find here
Benjamin Klotz
@tak1n
Apr 04 2016 13:29
the fear I have with it that its too different to get "mainstream"
I'mean I will definitely use it in future, and also try other dry stuff out :)
and I really hope the best for dry-rb and also rom :D
Piotr Solnica
@solnic
Apr 04 2016 13:30
it can become mainstream when there’s a full stack with conventions ready
so that people don’t have to think too much when they do basic stuff
because that’s what rails offers
Benjamin Klotz
@tak1n
Apr 04 2016 13:31
yep
Piotr Solnica
@solnic
Apr 04 2016 13:31
and by no means this is not me being negative about anything, just stating facts here
I think I should explain dry-v philosophy in the intro docs
I’m not happy with the current intro page
you gotta understand things like what it means to define the schema, that we’re validating structure just like we validate values
and that type safety is a first class feature, your domain validation rules can rely on valid values
Benjamin Klotz
@tak1n
Apr 04 2016 13:33
yep getting the concepts up in front seems really important to me
Piotr Solnica
@solnic
Apr 04 2016 13:34
there’s an ongoing discussion about splitting validation into 2 steps, one for basic structure/type checking, and another for applying domain rules
Benjamin Klotz
@tak1n
Apr 04 2016 13:34
where is this discussion happening?
IMO it would be a good idea to seperate this
Piotr Solnica
@solnic
Apr 04 2016 13:36
here and there :laughing:
here being here, there being github issues :)
it’s just that me and some other people mentioned this on multiple occasions
I will create a dedicated issue about it once I put my thoughts together
Benjamin Klotz
@tak1n
Apr 04 2016 13:41
okay cool :D
Benjamin Klotz
@tak1n
Apr 04 2016 15:07
how can u validate the length of a string?
Piotr Solnica
@solnic
Apr 04 2016 15:07
@tak1n :size?
Benjamin Klotz
@tak1n
Apr 04 2016 15:07
ah fuck yes
haha
too much for today haha
i tried smth crazy like: content.size.lteq?(120)
Piotr Solnica
@solnic
Apr 04 2016 15:08
well, don’t worry about this, looks like it’s I forgot to document :size?
I fail to see it there O_o
Benjamin Klotz
@tak1n
Apr 04 2016 15:08
okay :D
Piotr Solnica
@solnic
Apr 04 2016 15:08
oh wait, it IS there
although there’s no example with a string
it works with array, hash and string types
Benjamin Klotz
@tak1n
Apr 04 2016 15:08
ah okay :D
Piotr Solnica
@solnic
Apr 04 2016 15:09
and accepts an int or range
Benjamin Klotz
@tak1n
Apr 04 2016 15:09
cool thx
Piotr Solnica
@solnic
Apr 04 2016 15:09
and you can have custom errors based on the value type :D
all that using a single predicate :dancers:
Benjamin Klotz
@tak1n
Apr 04 2016 15:09
pretty awesome :D
Piotr Solnica
@solnic
Apr 04 2016 15:10
this is a general feature for all predicates
you can define a custom predicate and provide custom messages for each value type it supports
Benjamin Klotz
@tak1n
Apr 04 2016 15:38
yep already saw that :)
from the doc:
key?

Checks that a key is present in the input.
shouldn't this be Checks that a key's value is present in the input ?
I mean we already say with key(:whatever) that it is not optional
Piotr Solnica
@solnic
Apr 04 2016 15:41
yeah, this should probably be skipped, it’s a very low-level predicate
otoh MAYBE there are some use cases for it
key(:foo).required(:hash?, key?: :bar)
would check if foo is a hash and if it has a key called :bar
Benjamin Klotz
@tak1n
Apr 04 2016 15:42
ah okay
I thought its the opposite of none? where you check for presence xD
I'm too confused for today haha
Piotr Solnica
@solnic
Apr 04 2016 15:44
uhm, why would you think that? :)
Benjamin Klotz
@tak1n
Apr 04 2016 15:44
idk I'm currently totally confused xDD
Piotr Solnica
@solnic
Apr 04 2016 15:45
about what exactly?
Benjamin Klotz
@tak1n
Apr 04 2016 15:45
for example I have a limit restriction on the content
depending on which platform I wnat to post to
do I implement that as seperate rules?
curerntly I have smth like:
rule(facebook_limit: [:type, :content, :platform]) do |type, content, platform|
            platform.eql?('facebook').then(content.max_size?(FACEBOOK_LIMIT))
          end

          rule(twitter_limit: [:type, :content, :platform]) do |type, content, platform|
            platform.eql?('twitter').then(content.max_size?(TWITTER_LIMIT))
          end

          rule(linkedin_limit: [:type, :content, :platform]) do |type, content, platform|
            platform.eql?('linkedin').then(content.max_size?(LINKEDIN_LIMIT))
          end

          rule(xing_limit: [:type, :content, :platform]) do |type, content, platform|
            platform.eql?('xing').then(content.max_size?(XING_LIMIT))
          end
but then again content is optional so I somehow have to say trigger this rules only when content is not empty

before that I had 1 rule :limit where I had multiple then's in it

  rule(limit: [:type, :content, :platform]) do |type, content, platform|
    platform.eql?('facebook').then(content.max_size?(FACEBOOK_LIMIT) |
    platform.eql?('twitter').then(content.max_size?(TWITTER_LIMIT) |
     .
     .
  end

which didn't work at all :D

Piotr Solnica
@solnic
Apr 04 2016 15:49
I’ll look into implementing this
and get back to you
Benjamin Klotz
@tak1n
Apr 04 2016 15:50
okay thx :)
I can pm u the spec which I have for now if that would help
Piotr Solnica
@solnic
Apr 04 2016 15:51
I’ve got enough info, thanks
Benjamin Klotz
@tak1n
Apr 04 2016 15:51
kk
François Bernier
@fbernier
Apr 04 2016 16:58
class User < Dry::Types::Struct
  constructor_type(:schema)
  attribute :test, Dry::Types['hash']
end

class Admin < User; end;

p User.constructor_type
=> :schema
p Admin.constructor_type
=> :strict
expected?
Piotr Solnica
@solnic
Apr 04 2016 16:58
bug
François Bernier
@fbernier
Apr 04 2016 16:58
known bug?
Piotr Solnica
@solnic
Apr 04 2016 16:59
since 1 minute, yes ;)
François Bernier
@fbernier
Apr 04 2016 16:59
alright ;) I can take a stab at it if you want.
Piotr Solnica
@solnic
Apr 04 2016 16:59
would be great
François Bernier
@fbernier
Apr 04 2016 17:06
pushing a PR soon
John Backus
@backus
Apr 04 2016 19:13
require 'dry/types'

Types = Module.new.include(Dry::Types.module)

class Name < Dry::Types::Struct
  constructor_type(:schema)

  attribute :created_at, Types::Strict::DateTime.default { Time.now }
  attribute :first, Types::Strict::String
  attribute :last, Types::Strict::String
end

Name.new # => #<Name created_at=2016-04-04 12:13:28 -0700 first=nil last=nil>
Is this the intended behavior of constructor_type(:schema) even when attributes are defined as strict, @solnic?
I would expect that it would throw an error due to those nil values
Piotr Solnica
@solnic
Apr 04 2016 19:32
@backus probably a bug
John Backus
@backus
Apr 04 2016 19:32
ok. If it is definitely a bug then I can fix it right now
@solnic what can I show you that will convince you it is definitely a bug?
Piotr Solnica
@solnic
Apr 04 2016 20:24
@backus a pr with a fix :)
John Backus
@backus
Apr 04 2016 20:29
Ah cool. I figured maybe you considered it desired behavior
John Backus
@backus
Apr 04 2016 20:56
So the main issue @solnic is that the specified behavior is it 'uses :safe constructor when constructor_type is overridden' and it doesn't seem like there is a way around that
I just want the strict constructor that lets me omit keys for default values but nothing else

and there doesn't seem to be a way to avoid the Safe default since the constructor is determined by this line

@constructor = Types['coercible.hash'].public_send(constructor_type, schema)

and therefore I can't change the class that schema uses since it is the second argument:

module Dry
  module Types
    class Hash < Definition
      def schema(type_map, klass = Safe)
        # ...
      end
    end
  end
end

I can write @constructor = Types['coercible.hash'].schema(schema, Strict) after my type definitions

edit: ignore that ^. that would be equivalent to calling constructor_type(:strict)

but that seems like a hack
John Backus
@backus
Apr 04 2016 21:01
Maybe I'm proposing a feature and not fixing a bug. I don't know
John Backus
@backus
Apr 04 2016 21:31
Ah ok I think I've figured out how to address this. After a Safe schema has resolved missing keys belonging to Default and Maybe types it should evaluate the result using Strict
Nikita Shilnikov
@flash-gordon
Apr 04 2016 22:24
@backus I think there is no reason to evaluate the result for Maybe because it just would be None
John Backus
@backus
Apr 04 2016 23:02
@flash-gordon issue there is that omitted keys are set to nil then
John Backus
@backus
Apr 04 2016 23:38
Ok calling Strict after evaluating Schema or Symbolized hash schemas isn't really an option since they shouldn't blow up when given a hash with missing keys :(. I'm just going to PR a new schema type. :strict_with_defaults I guess.