Method: JSI::SchemaClasses.module_for_schema

Defined in:
lib/jsi/schema_classes.rb

.module_for_schema(schema_object, conflicting_modules: []) ⇒ Object

a module for the given schema, with accessor methods for any object property names the schema identifies. also has a singleton method called #schema to access the JSI::Schema this module represents.

accessor methods are defined on these modules so that methods can be defined on JSI.class_for_schema classes without method redefinition warnings. additionally, these overriding instance methods can call super to invoke the normal accessor behavior.

no property names that are the same as existing method names on the JSI class will be defined. users should use #[] and #[]= to access properties whose names conflict with existing methods.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/jsi/schema_classes.rb', line 47

def SchemaClasses.module_for_schema(schema_object, conflicting_modules: [])
  schema__ = JSI::Schema.from_object(schema_object)
  memoize(:module_for_schema, schema__, conflicting_modules) do |schema_, conflicting_modules_|
    Module.new.tap do |m|
      m.instance_exec(schema_) do |schema|
        define_singleton_method(:schema) { schema }
        define_singleton_method(:schema_id) do
          schema.schema_id
        end
        define_singleton_method(:inspect) do
          %Q(#<Module for Schema: #{schema_id}>)
        end

        conflicting_instance_methods = (conflicting_modules_ + [m]).map do |mod|
          mod.instance_methods + mod.private_instance_methods
        end.inject(Set.new, &:|)
        accessors_to_define = schema.described_object_property_names.map(&:to_s) - conflicting_instance_methods.map(&:to_s)
        accessors_to_define.each do |property_name|
          define_method(property_name) do
            if respond_to?(:[])
              self[property_name]
            else
              raise(NoMethodError, "schema instance of class #{self.class} does not respond to []; cannot call reader '#{property_name}'. instance is #{instance.pretty_inspect.chomp}")
            end
          end
          define_method("#{property_name}=") do |value|
            if respond_to?(:[]=)
              self[property_name] = value
            else
              raise(NoMethodError, "schema instance of class #{self.class} does not respond to []=; cannot call writer '#{property_name}='. instance is #{instance.pretty_inspect.chomp}")
            end
          end
        end
      end
    end
  end
end