These are chat archives for dry-rb/chat

24th
Jun 2016
Keith Pitty
@keithpitty
Jun 24 2016 03:28
@timriley just caught up on your talk via the live stream. :clap: :clap: :clap:
I really must make time to explore dry-rb
keithpitty @keithpitty pondering the best way to dive in
Tim Riley
@timriley
Jun 24 2016 04:12
@mrbongiolo @tak1n thanks!
@keithpitty Thanks for watching! Will you be at Rails Camp?
Keith Pitty
@keithpitty
Jun 24 2016 04:48
@timriley unfortunately no. We fly out to London for our family European holiday on the Saturday of the Rails Camp weekend. Our flights were already booked before the Rails Camp dates were announced.
On the plus side we are briefly visiting Poland in August so I guess there may be a chance for me to meet @solnic.
Andy Nicholson
@anicholson
Jun 24 2016 05:05

@solnic / @timriley hi!

@apotonick and I found a weird inconsistency in dry-v when debugging some odd behaviour in Reform: https://gist.github.com/anicholson/ba2cfe4fbb469b1aa01f7597056e7108

tl;dr —> Reform stringifies its input keys, and this causes inconsistent behaviour between the maybe and required macros. required seems to be able to handle this, but maybe breaks in surprising ways

HEAD of the above gist shows how I've been able to work around the issue, while HEAD~1 shows the odd behaviour in action

Tim Riley
@timriley
Jun 24 2016 06:06
@anicholson thanks for looking into this! Would you mind filing a GH issue with this included? That’ll make sure we don’t lose track of it. I suspect solnic will have something to say :)
Piotr Solnica
@solnic
Jun 24 2016 08:06
@anicholson I’m pretty sure it will work with stuff from master
@anicholson you may want to ask @fran-worley about it though
Peter Leitzen
@splattael
Jun 24 2016 09:14
dry for crystal: https://github.com/dry-cr by @ttdonovan :sparkles: yay :D
Wilson Silva
@wilsonsilva
Jun 24 2016 14:57
This message was deleted
Joshua Wilcox
@joshuaswilcox
Jun 24 2016 14:57
So working with dry transaction I see register :thing, -> stuff, input {...} in the docs, but i am wondering how I do the same thing to pass the splat to a class that gets called instead of using -> {...}
for example i have
register :my_validation do
  ValidateThings::Email.new
end
but within the class I would like the call to be able to accept more than just input
register :thing do |other, input| did not work
Andy Holland
@AMHOL
Jun 24 2016 15:15
@joshuaswilcox that is when registering with the container, to use options in steps you can do this
Joshua Wilcox
@joshuaswilcox
Jun 24 2016 15:18
thanks i'll take a look
Tim Riley
@timriley
Jun 24 2016 15:57
Yep, that's how you do it.
John Backus
@backus
Jun 24 2016 18:15
I'm thinking about creating something like dry/types/rspec
just so that something like this
class User < Dry::Types::Struct
  attribute :name, Name
  attribute :age, Dry::Types['strict.int']
end

User.new(instance_double(Types::Name), 22)
Obviously would only require it in specs
Basically it would be similar to the IceNine rspec adapter https://github.com/mbj/devtools/blob/master/shared/spec/support/ice_nine_config.rb
if defined?(IceNine)
  module IceNine

    # Freezer namespace
    class Freezer

      # Rspec freezer
      class RSpec < NoFreeze; end

    end # Freezer
  end # IceNine
end
John Backus
@backus
Jun 24 2016 21:44
Is this intended behavior?
require 'bundler/setup'
require 'dry/types'

class Thing < Dry::Types::Value
  attribute :value, Dry::Types['strict.int']

  class Null < Dry::Types::Value
  end
end

thing      = Thing.new(value: 100)                                         # => #<Thing value=100>
null_thing = Thing::Null.new                                               # => #<Thing::Null>

Dry::Types['thing']                                                        # => #<Dry::Types::Constructor type=#<Dry::Types::Definition primitive=Thing options={}>>
Dry::Types['thing.null']                                                   # => #<Dry::Types::Constructor type=#<Dry::Types::Definition primitive=Thing::Null options={}>>

# Behaves properly when given its own type
Dry::Types['thing'].call(thing)                                            # => #<Thing value=100>
Dry::Types['thing.null'].call(null_thing)                                  # => #<Thing::Null>

# Fails when trying to coerce Thing::Null to Thing
Dry::Types['thing'].call(null_thing)                                       # => (Dry::Types::StructError)

# Coerces Thing to Thing::Null though
Dry::Types['thing.null'].call(thing)                                       # => #<Thing::Null>

# Behavior becomes more surprising when you have a sum type of (thing | thing.null)
null_or_thing = Dry::Types['thing.null'] | Dry::Types['thing']             # => #<Dry::Types::Sum left=#<Dry::Types::Constructor type=#<Dry::Types::Definition primitive=Thing::Null options={}>> right=#<Dry::Types::Constructor type=#<Dry::Types::Definition primitive=Thing options={}>> options={}>
thing_or_null = Dry::Types['thing'] | Dry::Types['thing.null']             # => #<Dry::Types::Sum left=#<Dry::Types::Constructor type=#<Dry::Types::Definition primitive=Thing options={}>> right=#<Dry::Types::Constructor type=#<Dry::Types::Definition primitive=Thing::Null options={}>> options={}>

null_or_thing.call(thing)                                                  # => #<Thing::Null>
null_or_thing.call(null_thing)                                             # => #<Thing::Null>
thing_or_null.call(thing)                                                  # => #<Thing value=100>
thing_or_null.call(null_thing)                                             # => (Dry::Types::ConstraintError)

# Array of "things" or "null things" is basically not useable
Dry::Types['strict.array'].member(null_or_thing).call([thing, null_thing]) # => [#<Thing::Null>, #<Thing::Null>]
Dry::Types['strict.array'].member(thing_or_null).call([thing, null_thing]) # => (Dry::Types::ConstraintError)
cc @solnic ^
John Backus
@backus
Jun 24 2016 22:05
Bonus question: what about this?
require 'bundler/setup'
require 'dry/types'

class Foo < Dry::Types::Struct
end

Dry::Types[Foo].constrained(type: Foo).call(nil) # => #<Foo>
Nikita Shilnikov
@flash-gordon
Jun 24 2016 22:09
@backus are using dry-t from master?
John Backus
@backus
Jun 24 2016 22:15
yeah
well a very recent master
so 3 commits behind master
Ah I see you committed a ton of struct stuff
I'll try to upgrade it
Nikita Shilnikov
@flash-gordon
Jun 24 2016 22:17
yep :)
John Backus
@backus
Jun 24 2016 22:17
IMO I think dry-types structs should be extracted to dry-struct
Nikita Shilnikov
@flash-gordon
Jun 24 2016 22:17
but I still see some weird results with your example, even with the latest changes
John Backus
@backus
Jun 24 2016 22:17
It has a lot more complexity than is obvious at first I think
and we use dry-types structs for a lot of things
I think having it be a separate gem would be a good thing
dry-types could even require it
I just want to help and contribute a dry-types struct test suite basically
but when it is one detail of a bigger project that is tough
John Backus
@backus
Jun 24 2016 22:24
@flash-gordon your changes are a big improvement thank you!
I think the remaining weirdness boils down to dry-types struct code behaving weirdly if it is defined with zero attributes
Nikita Shilnikov
@flash-gordon
Jun 24 2016 22:28
struct is a single class built on top of dry-t stuff. One class, literally, so it depends on dry-t, not vice versa. We have nearly one file with specs for it. But any decision about extracting is for @solnic :)
@backus I'm glad it helped, this is a side effect :)
@backus I think you are right about reasons, could you raise an issue?
Nikita Shilnikov
@flash-gordon
Jun 24 2016 22:35
Thing::Null[Thing.new(value: 100)] # => #<Thing::Null> weird :)
Nikita Shilnikov
@flash-gordon
Jun 24 2016 23:07
in a nutshell Struct.[] implicitly calls to_hash on the argument so Thing.new(value: 100) becomes { value: 100 } and it is a valid input for struct because superfluous keys are silently ignored by strict scheme