Module: JSI::SchemaClasses
- Extended by:
- Memoize
- Defined in:
- lib/jsi/schema_classes.rb
Overview
this module is just a namespace for schema classes.
Class Method Summary collapse
-
.[](schema_id) ⇒ Class subclassing JSI::Base
JSI::SchemaClasses[schema_id] returns a class for the schema with the given id, the same class as returned from JSI.class_for_schema.
-
.class_for_schema(schema_object) ⇒ Object
see class_for_schema.
-
.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.
Methods included from Memoize
Class Method Details
.[](schema_id) ⇒ Class subclassing JSI::Base
JSI::SchemaClasses[schema_id] returns a class for the schema with the given id, the same class as returned from JSI.class_for_schema.
9 10 11 |
# File 'lib/jsi/schema_classes.rb', line 9 def self.[](schema_id) @classes_by_id[schema_id] end |
.class_for_schema(schema_object) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/jsi/schema_classes.rb', line 18 def class_for_schema(schema_object) memoize(:class_for_schema, JSI::Schema.from_object(schema_object)) do |schema_| Class.new(Base).instance_exec(schema_) do |schema| define_singleton_method(:schema) { schema } define_method(:schema) { schema } include(JSI::SchemaClasses.module_for_schema(schema, conflicting_modules: [Base, BaseArray, BaseHash])) jsi_class = self define_method(:jsi_class) { jsi_class } SchemaClasses.instance_exec(self) { |klass| @classes_by_id[klass.schema_id] = klass } self end end end |
.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 |