class Dry::Struct

Typed {Struct} with virtus-like DSL for defining schema.

### Differences between dry-struct and virtus

{Struct} look somewhat similar to [Virtus][] but there are few significant differences:

{Struct} class can specify a constructor type, which uses [hash schemas][] to handle attributes in `.new` method.

[`dry-types`]: github.com/dry-rb/dry-types [Virtus]: github.com/solnic/virtus [hash schemas]: dry-rb.org/gems/dry-types/hash-schemas

@example

require 'dry-struct'

module Types
  include Dry.Types()
end

class Book < Dry::Struct
  attribute :title, Types::String
  attribute :subtitle, Types::String.optional
end

rom_n_roda = Book.new(
  title: 'Web Development with ROM and Roda',
  subtitle: nil
)
rom_n_roda.title #=> 'Web Development with ROM and Roda'
rom_n_roda.subtitle #=> nil

refactoring = Book.new(
  title: 'Refactoring',
  subtitle: 'Improving the Design of Existing Code'
)
refactoring.title #=> 'Refactoring'
refactoring.subtitle #=> 'Improving the Design of Existing Code'

Constants

Error

Raised when given input doesn't conform schema and constructor type

VERSION

@private

Attributes

__attributes__[R]

@!attribute [Hash{Symbol => Object}] attributes

attributes[R]

@!attribute [Hash{Symbol => Object}] attributes

Public Class Methods

new(attributes) click to toggle source

@param [Hash, each] attributes

# File lib/dry/struct.rb, line 115
def initialize(attributes)
  @attributes = attributes
end

Public Instance Methods

[](name) click to toggle source

Retrieves value of previously defined attribute by its' `name`

@param [String] name @return [Object]

@example

class Book < Dry::Struct
  attribute :title, Types::String
  attribute :subtitle, Types::String.optional
end

rom_n_roda = Book.new(
  title: 'Web Development with ROM and Roda',
  subtitle: nil
)
rom_n_roda[:title] #=> 'Web Development with ROM and Roda'
rom_n_roda[:subtitle] #=> nil
# File lib/dry/struct.rb, line 136
def [](name)
  @attributes.fetch(name) { raise MissingAttributeError, name }
end
__new__(changeset)
Alias for: new
deconstruct_keys(_keys) click to toggle source

Pattern matching support

@api private

# File lib/dry/struct.rb, line 204
def deconstruct_keys(_keys)
  attributes
end
inspect() click to toggle source

@return [String]

# File lib/dry/struct.rb, line 194
def inspect
  klass = self.class
  attrs = klass.attribute_names.map { |key| " #{key}=#{@attributes[key].inspect}" }.join
  "#<#{klass.name || klass.inspect}#{attrs}>"
end
new(changeset) click to toggle source

Create a copy of {Dry::Struct} with overriden attributes

@param [Hash{Symbol => Object}] changeset

@return [Struct]

@example

class Book < Dry::Struct
  attribute :title, Types::String
  attribute :subtitle, Types::String.optional
end

rom_n_roda = Book.new(
  title: 'Web Development with ROM and Roda',
  subtitle: '2nd edition'
)
  #=> #<Book title="Web Development with ROM and Roda" subtitle="2nd edition">

rom_n_roda.new(subtitle: '3rd edition')
  #=> #<Book title="Web Development with ROM and Roda" subtitle="3rd edition">
# File lib/dry/struct.rb, line 185
def new(changeset)
  new_attributes = self.class.schema.apply(changeset, skip_missing: true, resolve_defaults: false)
  self.class.load(__attributes__.merge(new_attributes))
rescue Types::SchemaError, Types::MissingKeyError, Types::UnknownKeysError => e
  raise Error, "[#{self}.new] #{e}"
end
Also aliased as: __new__
pretty_print(pp) click to toggle source
# File lib/dry/struct/extensions/pretty_print.rb, line 7
def pretty_print(pp)
  klass = self.class
  pp.group(1, "#<#{klass.name || klass.inspect}", ">") do
    pp.seplist(@attributes.keys, proc { pp.text "," }) do |column_name|
      column_value = @attributes[column_name]
      pp.breakable " "
      pp.group(1) do
        pp.text column_name
        pp.text "="
        pp.pp column_value
      end
    end
  end
end
to_h() click to toggle source

Converts the {Dry::Struct} to a hash with keys representing each attribute (as symbols) and their corresponding values

@return [Hash{Symbol => Object}]

@example

class Book < Dry::Struct
  attribute :title, Types::String
  attribute :subtitle, Types::String.optional
end

rom_n_roda = Book.new(
  title: 'Web Development with ROM and Roda',
  subtitle: nil
)
rom_n_roda.to_hash
  #=> {title: 'Web Development with ROM and Roda', subtitle: nil}
# File lib/dry/struct.rb, line 157
def to_h
  self.class.schema.each_with_object({}) do |key, result|
    result[key.name] = Hashify[self[key.name]] if attributes.key?(key.name)
  end
end
Also aliased as: to_hash
to_hash()
Alias for: to_h