Module: Structure::ClassMethods

Defined in:
lib/structure.rb,
lib/structure/double.rb

Overview

ClassMethods

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#attribute_namesObject (readonly)

Returns the value of attribute attribute_names


67
68
69
# File 'lib/structure.rb', line 67

def attribute_names
  @attribute_names
end

Instance Method Details

#attribute(name) ⇒ Object


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
# File 'lib/structure.rb', line 69

def attribute(name)
  name = name.to_s

  if name.chomp!("?")
    module_eval(<<-EOS, __FILE__, __LINE__)
      def #{name}?
        #{name}
      end
    EOS
  end

  module_eval(<<-EOS, __FILE__, __LINE__)
    def #{name}
      return @#{name} if defined?(@#{name})
      @#{name} = _#{name}
      @#{name}.freeze unless @#{name}.is_a?(Structure)

      @#{name}
    end
  EOS

  define_method("_#{name}", Proc.new)
  private "_#{name}"

  @attribute_names << name

  name.to_sym
end

#doubleObject


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
# File 'lib/structure/double.rb', line 4

def double
  klass = Class.new(self)

  (
    private_instance_methods(false) +
    protected_instance_methods(false) -
    [:initialize]
  ).each do |name|
    klass.send(:undef_method, name)
  end

  klass.module_eval do
    def initialize(data = {})
      data.each do |key, value|
        unless value.is_a?(Structure) ||
               (
                  defined?(RSpec::Mocks::Double) &&
                  value.is_a?(RSpec::Mocks::Double)
               )
          value.freeze
        end

        instance_variable_set(:"@#{key}", value)
      end
    end

    attribute_names.each do |name|
      module_eval "def _#{name}; @#{name}; end"
      private "_#{name}"
    end

    module_eval(&Proc.new) if block_given?
  end

  class << klass
    undef_method :double
  end

  klass
end