have a full_attributes in dry-struct to be consistent with attribute_names?

currently when a struct is non-strict and an attribute is optional. calling attributes return a hash which doesn’t not include the attribute with nil value.
it might not be consistent with the attribute_names, because it has all the attributes.

So thinking to have a new method ‘full_attributes’ to return all the available attributes ,even though some values are nil.

module Types
   include Dry.Types()
end
[2] pry(main)> class User < Dry::Struct
[2] pry(main)*   schema schema.strict(false)
[2] pry(main)*   attribute? :name, Types::String.optional
[2] pry(main)*   attribute? :age, Types::Integer.optional
[2] pry(main)* end
=> User
[3] pry(main)> User.attribute_names
=> [:name, :age]
[4] pry(main)> u = User.new(name: 'a')
=> #<User name="a" age=nil>
[5] pry(main)> u.attributes
=> {:name=>"a"}

hoping to have a method to return {name: ‘a’, age: nil}, no matter it is called full_attributes or whatever.

In general I would advise against being so lax with your attributes, there is an important distinction being made here about whether a key is absent or explicitly set to nil.

If there are unavoidable reasons why you need this, it would be simple enough to construct an instance method that does this.

def full_attributes
  missing = self.class.attribute_names - attributes.keys
  attributes.merge(missing.zip([]).to_h)
end
1 Like
attribute :age, Types::Integer.optional.default(nil)

Is an alternative. One can make a constructor for types

Dry::Types.define_builder(:default_nil) do |type|
  types.optional.default(nil)
end

attribute :age, Types::Integer.default_nil
1 Like