lib/yasl/loader.rb in yasl-0.2.0 vs lib/yasl/loader.rb in yasl-0.2.1
- old
+ new
@@ -44,40 +44,39 @@
def load_structure(structure, for_classes: false)
if top_level_class?(structure)
class_for(structure['_class'])
elsif YASL.json_basic_data_type?(structure) && !(structure.is_a?(String) && structure.start_with?('_'))
structure
- elsif (structure['_class'] && (structure['_data'] || !structure.keys.detect {|key| key.start_with?('_') && key != '_class'} ))
+ elsif ruby_basic_data_type_structure?(structure)
load_ruby_basic_data_type_object(structure['_class'], structure['_data'])
- elsif structure['_class'] && (structure['_id'] || structure['_instance_variables'] || structure['_class_variables'] || structure['_struct_member_values'])
+ elsif load_non_basic_data_type_structure?(structure)
load_non_basic_data_type_object(structure)
end
end
private
+ def ruby_basic_data_type_structure?(structure)
+ (structure['_class'] && (structure['_data'] || !structure.keys.detect {|key| key.start_with?('_') && key != '_class'} ))
+ end
+
+ def load_non_basic_data_type_structure?(structure)
+ structure['_class'] && (structure['_id'] || structure['_instance_variables'] || structure['_class_variables'] || structure['_struct_member_values'])
+ end
+
def load_non_basic_data_type_object(structure, for_classes: false)
class_name = structure['_class']
object_class = class_for(class_name)
object_class.alias_method(:initialize_without_yasl, :initialize)
object = object_for_id(object_class, structure['_id'])
if object.nil?
object = for_classes ? object_class : object_class.new
- add_to_class_array(object, structure['_id']) if !object.is_a?(Class) && !object.is_a?(Module)
+ add_to_class_array(object, structure['_id'])
end
- structure['_instance_variables'].to_a.each do |instance_var, value|
- value = load_structure(value)
- object.instance_variable_set("@#{instance_var}".to_sym, value)
- end
- structure['_struct_member_values'].to_a.each do |member, value|
- value = load_structure(value)
- object[member.to_sym] = value
- end
- structure['_class_variables'].to_a.each do |class_var, value|
- value = load_structure(value)
- object.class_variable_set("@@#{class_var}".to_sym, value)
- end
+ structure['_class_variables'].to_a.each { |class_var, value| object.class_variable_set("@@#{class_var}".to_sym, load_structure(value)) }
+ structure['_instance_variables'].to_a.each { |instance_var, value| object.instance_variable_set("@#{instance_var}".to_sym, load_structure(value)) }
+ structure['_struct_member_values'].to_a.each { |member, value| load_struct_member_value(object, member, value) }
object
ensure
object_class&.define_method(:initialize, object_class.instance_method(:initialize_without_yasl))
end
@@ -104,13 +103,11 @@
when 'Range'
Range.new(*data)
when 'Array'
data.map {|element| load_structure(element)}
when 'Hash'
- data.reduce({}) do |new_hash, pair|
- new_hash.merge(load_structure(pair.first) => load_structure(pair.last))
- end
+ data.reduce({}) { |new_hash, pair| new_hash.merge(load_structure(pair.first) => load_structure(pair.last)) }
end
end
private
@@ -118,11 +115,11 @@
class_name_components = class_name.to_s.split('::')
current_class = Object
object_class = class_name_components.reduce(Object) do |result_class, class_name|
result_class.const_get(class_name)
end
- if !@whitelist_classes.include?(object_class)
+ if ![@whitelist_classes].compact.flatten.map(&:to_s).include?(object_class.to_s)
raise "Class `#{class_name}` is not mentioned in `whitelist_classes` (e.g. `YASL.load(data, whitelist_classes: [#{class_name}])`)!"
end
object_class
rescue NameError
# TODO materialize a class matching the non-existing class
@@ -131,14 +128,10 @@
def top_level_class?(structure)
structure && structure.is_a?(Hash) && structure['_class'] && structure['_id'].nil? && structure['_instance_variables'].nil? && structure['_class_variables'].nil? && structure['_struct_member_values'].nil? && structure['_data'].nil?
end
- def add_to_classes(object)
- classes << object unless classes.include?(object)
- end
-
def class_objects_for(object_class)
class_objects[object_class] ||= {}
end
def object_for_id(object_class, class_object_id)
@@ -146,13 +139,22 @@
return unless (object_class.is_a?(Class) || object_class.is_a?(Module))
class_objects_for(object_class)[class_object_id.to_i]
end
def add_to_class_array(object, class_object_id)
- return if class_object_id.nil?
+ return if object.is_a?(Class) || object.is_a?(Module) || class_object_id.nil?
object_class = object.class
found_object = object_for_id(object_class, class_object_id)
class_objects_for(object_class)[class_object_id.to_i] = object unless found_object
end
+ def load_struct_member_value(object, member, value)
+ value = load_structure(value)
+ begin
+ object[member.to_sym] = value
+ rescue => e
+ puts "#{e.message}. Setting `@#{member}` instance variable instead."
+ object.instance_variable_set("@#{member}".to_sym, value)
+ end
+ end
end
end