Skip to content

Commit

Permalink
Merge 2f9bfa9 into bb04f69
Browse files Browse the repository at this point in the history
  • Loading branch information
notEthan committed Feb 13, 2020
2 parents bb04f69 + 2f9bfa9 commit e823be4
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 15 deletions.
2 changes: 1 addition & 1 deletion lib/jsi/metaschema_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def initialize(node_document, node_ptr: JSI::JSON::Pointer[], metaschema_root_pt
end

if @schema
extend(JSI::SchemaClasses.module_for_schema(@schema, conflicting_modules: [Metaschema, Schema, MetaschemaNode, PathedArrayNode, PathedHashNode]))
extend(JSI::SchemaClasses.accessor_module_for_schema(@schema, conflicting_modules: [Metaschema, Schema, MetaschemaNode, PathedArrayNode, PathedHashNode]))
end

# workarounds
Expand Down
7 changes: 2 additions & 5 deletions lib/jsi/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,9 @@ def schema_id
end
end

# @param conflicting_modules [Enumerable<Module>] an array of modules (or classes) which
# may be used alongside the schema module. methods defined by any conflicting_module
# will not be defined as accessors for the JSI schema module.
# @return [Module] a module representing this schema. see {JSI::SchemaClasses.module_for_schema}.
def jsi_schema_module(conflicting_modules: [Base, BaseArray, BaseHash])
JSI::SchemaClasses.module_for_schema(self, conflicting_modules: conflicting_modules)
def jsi_schema_module
JSI::SchemaClasses.module_for_schema(self)
end

# @return [Class subclassing JSI::Base] shortcut for JSI.class_for_schema(schema)
Expand Down
27 changes: 20 additions & 7 deletions lib/jsi/schema_classes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,31 @@ def class_for_schema(schema_object)
#
# defines a singleton method #schema to access the {JSI::Schema} this module represents, and extends
# the module with {JSI::SchemaModule}.
#
# no property names that are the same as existing method names on given conflicting_modules will
# be defined. callers should use #[] and #[]= to access properties whose names conflict with such
# methods.
def SchemaClasses.module_for_schema(schema_object, conflicting_modules: [])
def module_for_schema(schema_object)
schema = JSI::Schema.from_object(schema_object)
jsi_memoize(:module_for_schema, schema, conflicting_modules) do |schema, conflicting_modules|
jsi_memoize(:module_for_schema, schema) do |schema|
Module.new.tap do |m|
m.instance_exec(schema) do |schema|
m.module_eval do
define_singleton_method(:schema) { schema }

extend SchemaModule

include JSI::SchemaClasses.accessor_module_for_schema(schema, conflicting_modules: [JSI::Base, JSI::BaseArray, JSI::BaseHash])
end
end
end
end

# @param schema [JSI::Schema] a schema for which to define accessors for any described property names
# @param conflicting_modules [Enumerable<Module>] an array of modules (or classes) which
# may be used alongside the accessor module. methods defined by any conflicting_module
# will not be defined as accessors.
# @return [Module] a module of accessors (setters and getters) for described property names of the given
# schema
def accessor_module_for_schema(schema, conflicting_modules: )
jsi_memoize(:accessor_module_for_schema, schema, conflicting_modules) do |schema, conflicting_modules|
Module.new.tap do |m|
m.module_eval do
conflicting_instance_methods = (conflicting_modules + [m]).map do |mod|
mod.instance_methods + mod.private_instance_methods
end.inject(Set.new, &:|)
Expand Down
3 changes: 1 addition & 2 deletions test/base_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,7 @@
}
end
it 'does not define readers' do
assert_equal('bar', subject.foo)
assert_equal(JSI::SchemaClasses.module_for_schema(subject.schema, conflicting_modules: [JSI::Base, JSI::BaseArray, JSI::BaseHash]), subject.method(:foo).owner)
assert_equal('bar', subject.foo) # this one is defined

assert_equal(JSI::Base, subject.method(:initialize).owner)
assert_equal('hi', subject['initialize'])
Expand Down

0 comments on commit e823be4

Please sign in to comment.