Class: YASL::Dumper

Inherits:
Object
  • Object
show all
Defined in:
lib/yasl/dumper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object) ⇒ Dumper

Returns a new instance of Dumper.



26
27
28
29
30
# File 'lib/yasl/dumper.rb', line 26

def initialize(object)
  @object = object
  @classes = []
  @class_objects = {}
end

Instance Attribute Details

#class_objectsObject (readonly)

Returns the value of attribute class_objects.



24
25
26
# File 'lib/yasl/dumper.rb', line 24

def class_objects
  @class_objects
end

#classesObject (readonly)

Returns the value of attribute classes.



24
25
26
# File 'lib/yasl/dumper.rb', line 24

def classes
  @classes
end

#objectObject (readonly)

Returns the value of attribute object.



24
25
26
# File 'lib/yasl/dumper.rb', line 24

def object
  @object
end

Instance Method Details

#dump(include_classes: false) ⇒ Object



32
33
34
35
36
# File 'lib/yasl/dumper.rb', line 32

def dump(include_classes: false)
  structure = dump_structure(object)
  structure.merge!(dump_classes_structure) if include_classes && structure.is_a?(Hash)
  structure
end

#dump_class_structure(klass) ⇒ Object



69
70
71
# File 'lib/yasl/dumper.rb', line 69

def dump_class_structure(klass)
  dump_structure(klass, for_classes: true) unless klass.class_variables.empty? && klass.instance_variables.empty?
end

#dump_class_variables(object) ⇒ Object



124
125
126
127
128
129
130
131
# File 'lib/yasl/dumper.rb', line 124

def dump_class_variables(object)
  structure = {}
  if object.respond_to?(:class_variables) && !object.class_variables.empty?
    structure[:_class_variables] = dump_class_variables_hash(object)
    structure.delete(:_class_variables) if structure[:_class_variables].empty?
  end
  structure
end

#dump_classes_structureObject



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/yasl/dumper.rb', line 55

def dump_classes_structure
  structure = {}
  structure[:_classes] ||= []
  @original_classes = []
  while classes.size > @original_classes.size
    diff = (classes - @original_classes)
    @original_classes = classes.clone
    diff.each { |klass| structure[:_classes] << dump_class_structure(klass) }
  end
  structure[:_classes] = structure[:_classes].compact
  structure.delete(:_classes) if structure[:_classes].empty?
  structure
end

#dump_instance_variables(object) ⇒ Object



133
134
135
136
137
138
139
140
# File 'lib/yasl/dumper.rb', line 133

def dump_instance_variables(object)
  structure = {}
  if !object.instance_variables.empty?
    structure[:_instance_variables] = dump_instance_variables_hash(object)
    structure.delete(:_instance_variables) if structure[:_instance_variables].empty?
  end
  structure
end

#dump_new_non_basic_data_type_structure(object) ⇒ Object



115
116
117
118
119
120
121
122
# File 'lib/yasl/dumper.rb', line 115

def dump_new_non_basic_data_type_structure(object)
  structure = {}
  structure[:_id] = add_to_class_array(object) unless object.is_a?(Class) || object.is_a?(Module)
  structure.merge!(dump_class_variables(object))
  structure.merge!(dump_instance_variables(object))
  structure.merge!(dump_struct_member_values(object))
  structure
end

#dump_non_basic_data_type_structure(object) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/yasl/dumper.rb', line 101

def dump_non_basic_data_type_structure(object)
  structure = {}
  klass = class_for(object)
  add_to_classes(klass)
  structure[:_class] = klass.name
  the_class_object_id = class_object_id(object)
  if the_class_object_id.nil?
    structure.merge!(dump_new_non_basic_data_type_structure(object))
  else
    structure[:_id] = the_class_object_id
  end
  structure
end

#dump_ruby_basic_data_type_data(obj) ⇒ Object



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
# File 'lib/yasl/dumper.rb', line 73

def dump_ruby_basic_data_type_data(obj)
  class_ancestors_names_include = lambda do |*class_names|
    lambda do |object|
      class_names.any? { |class_name| obj.class.ancestors.map(&:name).include?(class_name) }
    end
  end
  case obj
  when class_ancestors_names_include['Time']
    obj.to_datetime.marshal_dump
  when class_ancestors_names_include['Date']
    obj.marshal_dump
  when class_ancestors_names_include['Complex', 'Rational', 'Regexp', 'Symbol', 'BigDecimal']
    obj.to_s
  when class_ancestors_names_include['Set']
    obj.to_a.uniq.map {|element| dump_structure(element)}
  when class_ancestors_names_include['Range']
    [obj.begin, obj.end, obj.exclude_end?]
  when class_ancestors_names_include['Array']
    obj.map {|element| dump_structure(element)}
  when class_ancestors_names_include['Hash']
    obj.reject do |key, value|
      [key, value].detect {|element| unserializable?(element)}
    end.map do |pair|
      pair.map {|element| dump_structure(element)}
    end
  end
end

#dump_struct_member_values(object) ⇒ Object



142
143
144
145
146
147
148
149
# File 'lib/yasl/dumper.rb', line 142

def dump_struct_member_values(object)
  structure = {}
  if object.is_a?(Struct)
    structure[:_struct_member_values] = dump_struct_member_values_hash(object)
    structure.delete(:_struct_member_values) if structure[:_struct_member_values].empty?
  end
  structure
end

#dump_structure(object, for_classes: false) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/yasl/dumper.rb', line 38

def dump_structure(object, for_classes: false)
  return if unserializable?(object)
  structure = {}
  if top_level_class?(object, for_classes)
    structure[:_class] = object.name
    add_to_classes(object)
  elsif YASL.json_basic_data_type?(object)
    structure = object
  elsif YASL.ruby_basic_data_type?(object)
    structure[:_class] = object.class.name
    structure[:_data] = dump_ruby_basic_data_type_data(object)
  else
    structure.merge!(dump_non_basic_data_type_structure(object))
  end
  structure
end

#unserializable?(value) ⇒ Boolean

Returns:

  • (Boolean)


151
152
153
154
155
# File 'lib/yasl/dumper.rb', line 151

def unserializable?(value)
  result = UNSERIALIZABLE_DATA_TYPES.detect {|class_name| value.class.ancestors.map(&:name).include?(class_name.to_s)}
  result = ((value.is_a?(Class) || value.is_a?(Module)) && value.name.nil?) if result.nil?
  result
end