Module: SknUtils::AttributeHelpers

Included in:
NestedResultBase
Defined in:
lib/skn_utils/attribute_helpers.rb

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (private)

Adds the attr?() method pattern. all attributes will respond to attr?: example - obj.name? with true or false Adds the clear_attr() method pattern. all attributes will respond to clear_attr(): example - obj.clear_name sets :name to nil Handles getter for any instance_variable currently defined Handles setter for any instance_variable currently defined Sets new instance_variable for any undefined variable with non-hash value Sets instance_variable value to Bean object for any undefined variable with hash value param

Using any form of singleton_class() will break the generic bean, which requires Serialization. However not adding attr_accessors may impact performance, as method_missing must fill-in for read/writes

:nodoc:



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/skn_utils/attribute_helpers.rb', line 143

def method_missing(method, *args, &block)
  # puts("method_missing/method/class/*args=#{method}/#{method.class.name}/#{args}")
  if method.to_s.start_with?('clear_') and instance_variable_defined?("@#{method.to_s[6..-1]}")
    clear_attribute(method.to_s[6..-1].to_sym)
  elsif method.to_s.end_with?('?')
    if instance_variable_defined?("@#{method.to_s[0..-2]}")
      attribute?(method.to_s[0..-2].to_sym)
    else
      false
    end
  elsif method.to_s.end_with?("=")              # add new attribute or whole object
    if args.first.is_a?(Hash) 
      singleton_class.send(:attr_accessor, method.to_s[0..-2]) unless serial_required?
      if multi_required?
        instance_variable_set "@#{method.to_s[0..-2]}", self.class.new(*args)
      else
        instance_variable_set "@#{method.to_s[0..-2]}", *args
      end
    elsif args.first.is_a?(Array) and args.flatten.first.kind_of?(Hash)
      singleton_class.send(:attr_accessor, method.to_s[0..-2]) unless serial_required?
      if multi_with_arrays_required?
        instance_variable_set("@#{method.to_s[0..-2]}", 
            (args.first.map {|nobj| nobj.kind_of?(Hash) ? self.class.new(nobj) : nobj }) 
        )
      else
        instance_variable_set "@#{method.to_s[0..-2]}", *args
      end
    elsif !args.empty?
      singleton_class.send(:attr_accessor, method.to_s[0..-2]) unless serial_required?
      instance_variable_set "@#{method.to_s[0..-2]}", *args
    else
      super(method, *args, &block)      # throw excpt for not found or could return false
    end
  elsif instance_variable_defined? "@#{method.to_s}"
    instance_variable_get "@#{method.to_s}"
  else
    super(method, *args, &block)
  end
rescue
   # puts $!.message + $!.backtrace.join("\n")
  super(method, *args, &block)
end

Class Method Details

.included(mod) ⇒ Object

These methods normally come from ActiveSupport in Rails If your not using this gem with Rails, then the :included method will add these routines to the Object class



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/skn_utils/attribute_helpers.rb', line 35

def self.included(mod)
    unless Object.respond_to? :instance_variable_names  
      Object.class_exec {
        def instance_variable_names 
          instance_variables.map { |var| var.to_s } 
        end
        def instance_values
          Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
        end
      }
    end
end

Instance Method Details

#[](attr) ⇒ Object

An alternative mechanism for property access. Hash notation



71
72
73
# File 'lib/skn_utils/attribute_helpers.rb', line 71

def [](attr)
  send("#{attr}")
end

#[]=(attr, value) ⇒ Object

Hash notation



76
77
78
# File 'lib/skn_utils/attribute_helpers.rb', line 76

def []=(attr, value)
  send("#{attr}=", value)
end

#attributes(filter_internal = true) ⇒ Object

return a hash of all attributes and their current values including nested arrays of hashes/objects



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/skn_utils/attribute_helpers.rb', line 50

def attributes(filter_internal=true)
  instance_variable_names.each_with_object({}) do |attr,collector|
    next if ['skn_enable_serialization', 'skn_enabled_depth'].include?(attr.to_s[1..-1]) and filter_internal  # skip control keys
    value = instance_variable_get(attr)

    if value.kind_of?(Array) and value.first.respond_to?(:attribute_helper_object)
      value = value.map {|ov| ov.respond_to?(:attribute_helper_object) ? ov.attributes : ov }
    elsif value.respond_to?(:attribute_helper_object)
      value = value.attributes
    end
    collector[attr.to_s[1..-1].to_sym] = value
  end
end

#respond_to_missing?(method, incl_private = false) ⇒ Boolean

Support the regular respond_to? method by answering for any attr that method missing actually handle :nodoc:

Returns:

  • (Boolean)


87
88
89
# File 'lib/skn_utils/attribute_helpers.rb', line 87

def respond_to_missing?(method, incl_private=false)
   instance_variable_names.include?("@#{method.to_s}") || super(method,incl_private)
end

#to_hash(exclude_internal_vars = false) ⇒ Object Also known as: to_h



64
65
66
# File 'lib/skn_utils/attribute_helpers.rb', line 64

def to_hash(exclude_internal_vars=false)
  attributes(!exclude_internal_vars)
end