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}s don't provide attribute writers and are meant to be used as “data objects” exclusively.
-
Handling of attribute values is provided by standalone type objects from [`dry-types`][].
-
Handling of attribute hashes is provided by standalone hash schemas from [`dry-types`][].
-
Struct
classes quack like [`dry-types`][], which means you can use them in hash schemas, as array members or sum them
{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
@!attribute [Hash{Symbol => Object}] attributes
@!attribute [Hash{Symbol => Object}] attributes
Public Class Methods
@param [Hash, each] attributes
# File lib/dry/struct.rb, line 115 def initialize(attributes) @attributes = attributes end
Public Instance Methods
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
Pattern matching support
@api private
# File lib/dry/struct.rb, line 204 def deconstruct_keys(_keys) attributes end
@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
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
# 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
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