Class: Hashstructor::Member

Inherits:
Object
  • Object
show all
Defined in:
lib/hashstructor/member.rb

Overview

A member within a Hashstructor class that should be populated by the hash passed into #initialize.

Constant Summary

VALID_MEMBER_TYPES =

The allowed #member_types for a Member:

  • :normal - a normal value. raises error if hash or array given unless the :no_collections option is set.

  • :hash - a hash, with all keys symbolized unless the :string_keys option is set.

  • :array - an array

  • :set - a set

Note that these types refer to the “collection status” of the member. A :normal member will happily accept any value unless a :custom_type option is passed.

[ :normal, :hash, :set, :array ].freeze
VALID_VALUE_TYPES =

A hash of Class => Proc converters for value types. Any value type in this list, as well as any class that includes or prepends Hashstructor, is valid for #value_type. This is intentionally not frozen; if you want to extend it for your own use cases, I'm not going to get in your way.

{
  String => Proc.new do |v|
    v.to_s
  end,
  Symbol => Proc.new do |v|
    v.to_sym
  end,
  Integer => Proc.new do |v|
    Integer(v.to_s)
  end,
  Float => Proc.new do |v|
    Float(v.to_s)
  end,
  TrueClass => Proc.new do |v|
    !!v
  end,
  FalseClass => Proc.new do |v|
    !!v
  end,
}

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Member) initialize(klass, name, options)

Returns a new instance of Member

Raises:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/hashstructor/member.rb', line 80

def initialize(klass, name, options)
  member_type = options[:member_type] || :normal
  options.delete(:member_type)
  value_type = options[:value_type]
  options.delete(:value_type)
  required = !!(options[:required])
  options.delete(:required)
  attr_kind = options[:attr_kind]
  options.delete(:attr_kind)

  @options = options.freeze

  raise HashstructorError, "'name' must respond to :to_sym." unless name.respond_to?(:to_sym)
  @name = name.to_sym

  raise HashstructorError, "'member_type' (#{member_type}) must be one of: [ #{VALID_MEMBER_TYPES.join(", ")} ]" \
    unless VALID_MEMBER_TYPES.include?(member_type.to_sym)

  @member_type = member_type.to_sym

  raise HashstructorError, "'value_type' must be nil or a Class." \
    unless value_type == nil || value_type.is_a?(Class)
  raise HashstructorError, "'value_type' class, #{value_type.name}, must be in " +
        "VALID_VALUE_TYPES ([ #{VALID_VALUE_TYPES.keys.map { |c| c.name}.join(", ")} ]) " +
        "or include or prepend Hashstructor." \
    unless value_type == nil || VALID_VALUE_TYPES[value_type] != nil || value_type.ancestors.include?(Hashstructor)

  @value_type = value_type

  @required = required

  case attr_kind
  when nil
    # do nothing
  when :reader
    klass.send(:attr_reader, @name)
  when :accessor
    klass.send(:attr_accessor, @name)
  else
    raise HashstructorError, "Unrecognized attr_kind: #{attr_kind}"
  end
  @attr_kind = attr_kind
end

Instance Attribute Details

- ((nil, :reader, :accessor)) attr_kind (readonly)

Specifies what type of attr (nil, :reader, or :accessor) that this member should define on its class.

Returns:

  • ((nil, :reader, :accessor))

    the type of attr to create.



75
76
77
# File 'lib/hashstructor/member.rb', line 75

def attr_kind
  @attr_kind
end

- (Symbol) member_type (readonly)

Returns the type of the member; see VALID_MEMBER_TYPES.

Returns:



23
24
25
# File 'lib/hashstructor/member.rb', line 23

def member_type
  @member_type
end

- (Symbol) name (readonly)

Returns the name of the member, in the parsed hash.

Returns:

  • (Symbol)

    the name of the member, in the parsed hash.



20
21
22
# File 'lib/hashstructor/member.rb', line 20

def name
  @name
end

- (Hash) options (readonly)

Returns a (frozen) set of all extra options passed to the member.

Returns:

  • (Hash)

    a (frozen) set of all extra options passed to the member.



78
79
80
# File 'lib/hashstructor/member.rb', line 78

def options
  @options
end

- (Object) required (readonly)

If true, attempting to construct this object without setting this member will raise an error.



69
70
71
# File 'lib/hashstructor/member.rb', line 69

def required
  @required
end

- ((nil, Class)) value_type (readonly)

Determines the class that Hashstructor should attempt to coerce a given value into. For example, Fixnum will attempt to coerce a scalar value into a Fixnum.

The valid types for #value_type are:

  • String

  • Symbol

  • Integer

  • Float

  • TrueClass or FalseClass (for booleans)

  • any class that includes or prepends Hashstructor

Returns:

  • ((nil, Class))

    the type of the value stored in this member.



64
65
66
# File 'lib/hashstructor/member.rb', line 64

def value_type
  @value_type
end

Instance Method Details

- (Object) parse_single(value)

Parses the passed-in value (always a single item; InstanceMethods#hashstruct handles the breaking down of arrays and hashes) and returns a value according to #value_type.



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/hashstructor/member.rb', line 126

def parse_single(value)
  if value_type.nil?
    value
  elsif value_type.ancestors.include?(Hashstructor)
    raise HashstructorError, "No hash provided for building a Hashstructor object." unless value.is_a?(Hash)

    value_type.new(value)
  else
    VALID_VALUE_TYPES[value_type].call(value)
  end
end