Module: Pigeon::OptionAccessor

Included in:
Dispatcher, Engine
Defined in:
lib/pigeon/option_accessor.rb

Instance Method Summary collapse

Instance Method Details

#option_accessor(*args, boolean: false, default: nil, on: [ :class, :instance ]) ⇒ Object

Given a list of names, this declares an option accessor which works like a combination of cattr_accessor and attr_accessor, except that defaults defined for a class will propagate down to the instances and subclasses, but these defaults can be over-ridden in subclasses and instances without interference. Optional hash at end of list can be used to set:

* :default => Assigns a default value which is otherwise nil


8
9
10
11
# File 'lib/pigeon/option_accessor.rb', line 8

def option_accessor(*args, boolean: false, default: nil, on: [ :class, :instance ])
  option_reader(*args, boolean: boolean, default: default, on: on)
  option_writer(*args, boolean: boolean, on: on)
end

#option_reader(*names, boolean: false, default: nil, on: [ :class, :instance ]) ⇒ Object

Given a list of names, this declares an option reader which works like a combination of cattr_reader and attr_reader, except that defaults defined for a class will propagate down to the instances and subclasses, but these defaults can be over-ridden in subclasses and instances without interference. Optional hash at end of list can be used to set:

* :default => Assigns a default value which is otherwise nil
* :boolean => If true, creates an additional name? method and will
              convert all assigned values to a boolean true/false.


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
# File 'lib/pigeon/option_accessor.rb', line 21

def option_reader(*names, boolean: false, default: nil, on: [ :class, :instance ])
  names = [ names ].flatten.compact
  on = [ on ].flatten
  
  names.each do |name|
    iv = :"@#{name}"

    if (on.include?(:class))
      (class << self; self; end).class_eval do
        if (boolean)
          define_method(:"#{name}?") do
            iv_value = instance_variable_defined?(iv) ? instance_variable_get(iv) : nil

            !!(iv_value.nil? ? (self.superclass.respond_to?(name) ? self.superclass.send(name) : nil) : iv_value)
          end
        end

        define_method(name) do
          iv_value = instance_variable_defined?(iv) ? instance_variable_get(iv) : nil
          
          iv_value.nil? ? (self.superclass.respond_to?(name) ? self.superclass.send(name) : nil) : iv_value
        end
      end
    end
  
    if (on.include?(:instance))
      define_method(name) do
        iv_value = instance_variable_defined?(iv) ? instance_variable_get(iv) : nil

        iv_value.nil? ? self.class.send(name) : iv_value
      end

      if (boolean)
        define_method(:"#{name}?") do
          iv_value = instance_variable_defined?(iv) ? instance_variable_get(iv) : nil

          !!(iv_value.nil? ? self.class.send(name) : iv_value)
        end
      end
    end
    
    instance_variable_set(iv, default)
  end
end

#option_writer(*names, boolean: false, on: [ :class, :instance ]) ⇒ Object

Given a list of names, this declares an option writer which works like a combination of cattr_writer and attr_writer, except that defaults defined for a class will propagate down to the instances and subclasses, but these defaults can be over-ridden in subclasses and instances without interference.



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
# File 'lib/pigeon/option_accessor.rb', line 71

def option_writer(*names, boolean: false, on: [ :class, :instance ])
  names = [ names ].flatten.compact
  on = [ on ].flatten
  
  names.each do |name|
    iv = :"@#{name}"

    if (on.include?(:class))
      (class << self; self; end).class_eval do
        if (boolean)
          define_method(:"#{name}=") do |value|
            instance_variable_set(iv, value.nil? ? nil : !!value)
          end
        else
          define_method(:"#{name}=") do |value|
            instance_variable_set(iv, value)
          end
        end
      end
    end
  
    if (on.include?(:instance))
      if (boolean)
        define_method(:"#{name}=") do |value|
          instance_variable_set(iv, value.nil? ? nil : !!value)
        end
      else
        define_method(:"#{name}=") do |value|
          instance_variable_set(iv, value)
        end
      end
    end
  end
end