These are chat archives for dry-rb/chat

3rd
Apr 2016
John Backus
@backus
Apr 03 2016 00:25
@solnic Feel free to review #64
Russell Edens
@rx
Apr 03 2016 01:48
Hi I'm brand new to dry-types and I'm having trouble understanding why these spec's fail?
describe Types::Strict::String do
  let(:email) { Types::Strict::String.constrained(
      format: /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i) }

  it 'should be same?' do
    expect(email["jane@doe.org"]).to be("jane@doe.org")
  end

  it 'should be equal?' do
    expect(email["jane@doe.org"]).to be_equal("jane@doe.org")
  end
end
John Backus
@backus
Apr 03 2016 03:25
@rx is that rspec? If so try changing be to eql
Piotr Solnica
@solnic
Apr 03 2016 09:12
@rx you’d need to write this like that: v = “jane@doe.org”; expect(email[v]).to be(v)
be checks if the object is the same in terms of its identity, not equality
Tim Cooper
@coop
Apr 03 2016 09:14
JSON types got merged 😁
Piotr Solnica
@solnic
Apr 03 2016 09:16
@coop :) seems like we’re gonna have another nice release soon, @backus has done lots of great improvements/fixes too
John Backus
@backus
Apr 03 2016 09:16
:)
Piotr Solnica
@solnic
Apr 03 2016 09:18
@coop one thing to consider is using a shared module with these common coercions, I’m not sure if delegating to JSON in Form is a good way to do this
John Backus
@backus
Apr 03 2016 09:20
I was thinking of tossing these into Coercions as private methods and then doing extend Coercions inside JSON and Form @solnic
Er, the private method was for the empty_str? method I added. Others would be public of course
Tim Cooper
@coop
Apr 03 2016 09:22
@solnic I wasn't sure which way to go about it. At the moment you could make the change you're talking about and the tests wouldn't need to change. I could do that tonight?
Piotr Solnica
@solnic
Apr 03 2016 09:33
@coop sounds good
@backus yep a shared module like that would be better
John Backus
@backus
Apr 03 2016 09:37
Just finished investigating why rubinius and jruby are failing my builds
rbx :001 > foo = 0.0       # => 0.0
rbx :002 > bar = 0.0       # => 0.0
rbx :003 > foo.equal?(bar) # => false

mri :004 > foo = 0.0       # => 0.0
mri :005 > bar = 0.0       # => 0.0
mri :006 > foo.equal?(bar) # => true
k
Tim Cooper
@coop
Apr 03 2016 09:43
@backus it looks like you’re about to create a shared module between Form and JSON?
I need to do the same to share the (currently) delegated JSON methods in Form.
John Backus
@backus
Apr 03 2016 09:45
Yeah
I'm doing that right now
I'll share a diff with you in a minute
Tim Cooper
@coop
Apr 03 2016 09:46
Cool.
John Backus
@backus
Apr 03 2016 09:51
diff --git c/lib/dry/types/coercions.rb i/lib/dry/types/coercions.rb
new file mode 100644
index 0000000..357776d
--- /dev/null
+++ i/lib/dry/types/coercions.rb
@@ -0,0 +1,35 @@
+module Dry
+  module Types
+    module Coercions
+      EMPTY_STRING = ''.freeze
+
+      def to_nil(input)
+        input unless empty_str?(input)
+      end
+
+      def to_date(input)
+        Date.parse(input)
+      rescue ArgumentError
+        input
+      end
+
+      def to_date_time(input)
+        DateTime.parse(input)
+      rescue ArgumentError
+        input
+      end
+
+      def to_time(input)
+        Time.parse(input)
+      rescue ArgumentError
+        input
+      end
+
+      private
+
+      def empty_str?(value)
+        EMPTY_STRING.eql?(value)
+      end
+    end
+  end
+end
diff --git c/lib/dry/types/coercions/form.rb i/lib/dry/types/coercions/form.rb
index 7c1c2a1..253308f 100644
--- c/lib/dry/types/coercions/form.rb
+++ i/lib/dry/types/coercions/form.rb
@@ -8,23 +8,8 @@ module Dry
         TRUE_VALUES = %w[1 on  t true  y yes].freeze
         FALSE_VALUES = %w[0 off f false n no].freeze
         BOOLEAN_MAP = ::Hash[TRUE_VALUES.product([true]) + FALSE_VALUES.product([false])].freeze
-        EMPTY_STRING = ''.freeze

-        def self.to_nil(input)
-          JSON.to_nil(input)
-        end
-
-        def self.to_date(input)
-          JSON.to_date(input)
-        end
-
-        def self.to_date_time(input)
-          JSON.to_date_time(input)
-        end
-
-        def self.to_time(input)
-          JSON.to_time(input)
-        end
+        extend Coercions

         def self.to_true(input)
           BOOLEAN_MAP.fetch(input, input)
@@ -67,11 +52,6 @@ module Dry
             result
           end
         end
-
-        def self.empty_str?(value)
-          EMPTY_STRING.eql?(value)
-        end
-        private_class_method :empty_str?
       end
     end
   end
diff --git c/lib/dry/types/coercions/json.rb i/lib/dry/types/coercions/json.rb
index 287a559..7ba08e9 100644
--- c/lib/dry/types/coercions/json.rb
+++ i/lib/dry/types/coercions/json.rb
@@ -7,27 +7,7 @@ module Dry
   module Types
     module Coercions
       module JSON
-        def self.to_nil(input)
-          input unless ''.eql?(input)
-        end
-
-        def self.to_date(input)
-          Date.parse(input)
-        rescue ArgumentError
-          input
-        end
-
-        def self.to_date_time(input)
-          DateTime.parse(input)
-        rescue ArgumentError
-          input
-        end
-
-        def self.to_time(input)
-          Time.parse(input)
-        rescue ArgumentError
-          input
-        end
+        extend Coercions

         def self.to_decimal(input)
           if input.is_a?(String) && input == ''
diff --git c/lib/dry/types/core.rb i/lib/dry/types/core.rb
index 01fe20f..d438bbe 100644
--- c/lib/dry/types/core.rb
+++ i/lib/dry/types/core.rb
@@ -65,5 +65,6 @@ module Dry
   end
 end

+require 'dry/types/coercions'
 require 'dry/types/form'
 require 'dry/types/json'
@coop ^
Tim Cooper
@coop
Apr 03 2016 09:51
That looks good to me.
John Backus
@backus
Apr 03 2016 09:52
Cool
Pushed to #67
John Backus
@backus
Apr 03 2016 21:35
Not sure if mutant is regularly part of your workflow @solnic but if it is I found this helpful for making mutant work Dry::Types registry:
RSpec.configure do |config|
  config.before do
    container = Dry::Types.container._container
    container.keys.each(&container.method(:delete))

    load File.expand_path("#{__dir__}/../lib/dry/types/core.rb")
    load File.expand_path("#{__dir__}/../lib/dry/types/form.rb")
    load File.expand_path("#{__dir__}/../lib/dry/types/json.rb")
  end
end
John Backus
@backus
Apr 03 2016 21:48
Ok I feel a bit silly asking this since I just spent my Saturday adding tests to dry-types,
but I'm unclear on the point of things like Types::Int. What am I missing?
require 'dry/types'

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

# Attempts Kernel coercions. Makes sense
Types::Coercible::Int['1']   # => 1
Types::Coercible::Int[1.0]   # => 1
Types::Coercible::Int['one'] # !> invalid value for Integer(): "one" (ArgumentError)

# Rejects anything that isn't an integer. Makes sense
Types::Strict::Int[1]        # => 1
Types::Strict::Int['1']      # !> "1" violates constraints (type?(Integer) failed) (Dry::Types::ConstraintError)

# Doesn't coerce. Doesn't enforce anything. I don't understand
Types::Int['1']              # => "1"
Types::Int['one']            # => "one"
Types::Int[1.0]              # => 1.0
John Backus
@backus
Apr 03 2016 22:38
@solnic Dry::Types::Hash::Safe has zero test coverage (I can just remove the method body). Is this dead code or should there be tests?
Piotr Solnica
@solnic
Apr 03 2016 22:58
@backus Hash::Safe is used in dry-validation, there should be tests for it in dry-types
@backus Types::Definition#call could be removed assuming all its subclasses provide their own #call
@backus how is it possible that it has no coverage when we have CC reporting 100% cov?
John Backus
@backus
Apr 03 2016 23:01
Mutant coverage
Maybe the relevant method object is being passed around and mutations aren't being applied
re Definition#call: Cool. AbstractType is already an indirect dependency. It would be nice to then drop in an abstract_method in the place of the #call method
Piotr Solnica
@solnic
Apr 03 2016 23:07
@backus Hash::Safe has line coverage via struct specs
Piotr Solnica
@solnic
Apr 03 2016 23:13
@backus oh wait, I do want to keep Definition#call
it must be a no-op so that struct can work with plain definitions
John Backus
@backus
Apr 03 2016 23:18
Ah ok
Tim Riley
@timriley
Apr 03 2016 23:55
^^^ I was also confused by the Types::Int-style behaviour that @backus posted above.
Piotr Solnica
@solnic
Apr 03 2016 23:56
I removed it from docs
Tim Riley
@timriley
Apr 03 2016 23:57
So Types::Int – when not using the strict or coercible variations – is really more a “signal of good intentions?”
Piotr Solnica
@solnic
Apr 03 2016 23:58
No. It is just a definition. It defines a type w/o any constraints. Useful for inspection etc.
It is not supposed to be used for anything else than being a definition
Sorry it is 2am over here so I'm gonna :zzz: now
Tim Riley
@timriley
Apr 03 2016 23:59
Bye!