Module: JSI::SchemaClasses

Extended by:
Memoize
Defined in:
lib/jsi/base.rb

Overview

this module is just a namespace for schema classes.

Class Method Summary collapse

Methods included from Memoize

clear_memo, 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.

Parameters:

Returns:

  • (Class subclassing JSI::Base)

    the class for that schema



242
243
244
# File 'lib/jsi/base.rb', line 242

def self.[](schema_id)
  @classes_by_id[schema_id]
end

.class_for_schema(schema_object) ⇒ Object



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/jsi/base.rb', line 249

def SchemaClasses.class_for_schema(schema_object)
  if schema_object.is_a?(JSI::Schema)
    schema__ = schema_object
  else
    schema__ = JSI::Schema.new(schema_object)
  end

  memoize(:class_for_schema, schema__) do |schema_|
    begin
      begin
        Class.new(Base).instance_exec(schema_) do |schema|
          begin
            include(JSI::SchemaClasses.module_for_schema(schema))

            SchemaClasses.instance_exec(self) { |klass| @classes_by_id[klass.schema_id] = klass }

            self
          end
        end
      end
    end
  end
end

.module_for_schema(schema_object) ⇒ Object

a module for the given schema, with accessor methods for any object property names the schema identifies. also has class and instance methods 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.



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/jsi/base.rb', line 286

def SchemaClasses.module_for_schema(schema_object)
  if schema_object.is_a?(JSI::Schema)
    schema__ = schema_object
  else
    schema__ = JSI::Schema.new(schema_object)
  end

  memoize(:module_for_schema, schema__) do |schema_|
    Module.new.tap do |m|
      m.instance_exec(schema_) do |schema|
        define_method(:schema) { schema }
        define_singleton_method(:schema) { schema }
        define_singleton_method(:included) do |includer|
          includer.send(:define_singleton_method, :schema) { schema }
        end

        define_singleton_method(:schema_id) do
          schema.schema_id
        end
        define_singleton_method(:inspect) do
          %Q(#<Module for Schema: #{schema_id}>)
        end

        instance_method_modules = [m, Base, BaseArray, BaseHash]
        instance_methods = instance_method_modules.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) - 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, "instance does not respond to []; cannot call reader `#{property_name}' for: #{pretty_inspect.chomp}")
            end
          end
          define_method("#{property_name}=") do |value|
            if respond_to?(:[]=)
              self[property_name] = value
            else
              raise(NoMethodError, "instance does not respond to []=; cannot call writer `#{property_name}=' for: #{pretty_inspect.chomp}")
            end
          end
        end
      end
    end
  end
end