File: module_extensions.rb

package info (click to toggle)
ruby-virtus 2.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 660 kB
  • sloc: ruby: 4,378; makefile: 2
file content (88 lines) | stat: -rw-r--r-- 2,128 bytes parent folder | download | duplicates (3)
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
module Virtus

  # Virtus module that can define attributes for later inclusion
  #
  # @private
  module ModuleExtensions
    include ConstMissingExtensions

    # @api private
    def self.extended(mod)
      super
      setup(mod)
    end

    # @api private
    def self.setup(mod, inclusions = [Model], attribute_definitions = [])
      mod.instance_variable_set('@inclusions', inclusions)
      existing_attributes = mod.instance_variable_get('@attribute_definitions')
      new_attributes = (existing_attributes || []) + attribute_definitions
      mod.instance_variable_set('@attribute_definitions', new_attributes)
    end

    # Define an attribute in the module
    #
    # @see Virtus::Extensions#attribute
    #
    # @return [self]
    #
    # @api private
    def attribute(name, type = nil, options = {})
      @attribute_definitions << [name, type, options]
      self
    end

    private

    # Extend an object with Virtus methods and define attributes
    #
    # @param [Object] object
    #
    # @return [undefined]
    #
    # @api private
    def extended(object)
      super
      @inclusions.each { |mod| object.extend(mod) }
      define_attributes(object)
      object.set_default_attributes
    end

    # Extend a class with Virtus methods and define attributes
    #
    # @param [Object] object
    #
    # @return [undefined]
    #
    # @api private
    def included(object)
      super

      if Class === object
        @inclusions.reject do |mod|
          object.ancestors.include?(mod)
        end.each do |mod|
          object.send(:include, mod)
        end
        define_attributes(object)
      else
        object.extend(ModuleExtensions)
        ModuleExtensions.setup(object, @inclusions, @attribute_definitions)
      end
    end

    # Define attributes on a class or instance
    #
    # @param [Object,Class] object
    #
    # @return [undefined]
    #
    # @api private
    def define_attributes(object)
      @attribute_definitions.each do |attribute_args|
        object.attribute(*attribute_args)
      end
    end

  end # module ModuleExtensions
end # module Virtus