1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 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
|
module Virtus
# Extensions common for both classes and instances
module Extensions
WRITER_METHOD_REGEXP = /=\z/.freeze
INVALID_WRITER_METHODS = %w[ == != === []= attributes= ].to_set.freeze
RESERVED_NAMES = [:attributes].to_set.freeze
# A hook called when an object is extended with Virtus
#
# @param [Object] object
#
# @return [undefined]
#
# @api private
def self.extended(object)
super
object.instance_eval do
extend Methods
extend InstanceMethods
extend InstanceMethods::MassAssignment
end
end
private_class_method :extended
module Methods
# @api private
def self.extended(descendant)
super
descendant.extend(AttributeSet.create(descendant))
end
private_class_method :extended
# Defines an attribute on an object's class or instance
#
# @example
# class Book
# include Virtus.model
#
# attribute :title, String
# attribute :author, String
# attribute :published_at, DateTime
# attribute :page_count, Integer
# attribute :index # defaults to Object
# end
#
# @param [Symbol] name
# the name of an attribute
#
# @param [Class,Array,Hash,Axiom::Types::Type,String,Symbol] type
# the type class of an attribute
#
# @param [#to_hash] options
# the extra options hash
#
# @return [self]
#
# @see Attribute.build
#
# @api public
def attribute(name, type = nil, options = {})
assert_valid_name(name)
attribute_set << Attribute.build(type, options.merge(:name => name))
self
end
# @see Virtus.default_value
#
# @api public
def values(&block)
private :attributes= if instance_methods.include?(:attributes=)
yield
include(Equalizer.new(name, attribute_set.map(&:name)))
end
# The list of writer methods that can be mass-assigned to in #attributes=
#
# @return [Set]
#
# @api private
def allowed_writer_methods
@allowed_writer_methods ||=
begin
allowed_writer_methods = allowed_methods.grep(WRITER_METHOD_REGEXP).to_set
allowed_writer_methods -= INVALID_WRITER_METHODS
allowed_writer_methods.freeze
end
end
private
# Return an attribute set for that instance
#
# @return [AttributeSet]
#
# @api private
def attribute_set
@attribute_set
end
end # Methods
end # module Extensions
end # module Virtus
|