Skip to content

Commit

Permalink
Metas without constant initial implementation [#30 state:resolved]
Browse files Browse the repository at this point in the history
  • Loading branch information
yrashk committed Apr 30, 2008
1 parent 78c6023 commit 591e7fe
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 37 deletions.
3 changes: 3 additions & 0 deletions lib/strokedb/core_ext/string.rb
Expand Up @@ -31,6 +31,9 @@ def modulize
end

def constantize
if /^meta:/ =~ self
return StrokeDB::META_CACHE[Meta.make_uuid_from_fullname(self)]
end
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
raise NameError, "#{self.inspect} is not a valid constant name!"
end
Expand Down
13 changes: 10 additions & 3 deletions lib/strokedb/document.rb
Expand Up @@ -344,7 +344,6 @@ def self.from_raw(store, raw_slots, opts = {}) #:nodoc:
collect_meta_modules(store, raw_slots['meta']).each do |meta_module|
unless doc.is_a? meta_module
doc.extend(meta_module)

meta_module.send!(:setup_callbacks, doc) rescue nil
end
end
Expand Down Expand Up @@ -686,13 +685,21 @@ def self.collect_meta_modules(store, meta) #:nodoc:
if m = store.find($1, $2)
mod = Module.find_by_nsurl(m[:nsurl])
mod = nil if mod == Module
meta_names << (mod ? mod.name : "") + "::" + m[:name]
if (mod.nil? && Object.constants.include?(m[:name])) || (mod && mod.constants.include?(m[:name]))
meta_names << (mod ? mod.name : "") + "::" + m[:name]
else
meta_names << Meta.resolve_uuid_name(m[:nsurl],m[:name])
end
end
when DOCREF
if m = store.find($1)
mod = Module.find_by_nsurl(m[:nsurl])
mod = nil if mod == Module
meta_names << (mod ? mod.name : "") + "::" + m[:name]
if (mod.nil? && Object.constants.include?(m[:name])) || (mod && mod.constants.include?(m[:name]))
meta_names << (mod ? mod.name : "") + "::" + m[:name]
else
meta_names << Meta.resolve_uuid_name(m[:nsurl],m[:name])
end
end
when Array
meta_names = meta.map { |m| collect_meta_modules(store, m) }.flatten
Expand Down
39 changes: 25 additions & 14 deletions lib/strokedb/document/meta.rb
@@ -1,4 +1,7 @@
module StrokeDB

META_CACHE = {}

# Meta is basically a type. Imagine the following document:
#
# some_apple:
Expand All @@ -20,8 +23,21 @@ module StrokeDB
#
# Document class will be extended by modules Fruit and Product.
module Meta

class << self

def resolve_uuid_name(nsurl,name)
"meta:#{nsurl}##{name}"
end

def make_uuid_from_fullname(full_name)
StrokeDB::Util.sha1_uuid(full_name)
end

def make_uuid(nsurl, name)
StrokeDB::Util.sha1_uuid("meta:#{nsurl}##{name}")
end

def new(*args, &block)
mod = Module.new
args = args.unshift(nil) if args.empty? || args.first.is_a?(Hash)
Expand All @@ -44,8 +60,13 @@ def new(*args, &block)
initialize_coercions
initialize_virtualizations
end
if meta_name = extract_meta_name(*args)
Object.const_set(meta_name, mod)
if name = args.last.stringify_keys['name']
META_CACHE[make_uuid(args.last.stringify_keys['nsurl'],args.last.stringify_keys['name'])] = mod
mod.instance_eval %{
def name
'#{name}'
end
}
end
mod
end
Expand All @@ -65,14 +86,6 @@ def uuid
@uuid ||= ::Util.sha1_uuid("meta:#{StrokeDB.nsurl}##{Meta.name.demodulize}")
end

def extract_meta_name(*args)
if args.first.is_a?(Hash)
args.first[:name]
else
args[1][:name] unless args.empty?
end
end

end

def +(meta)
Expand Down Expand Up @@ -227,8 +240,6 @@ def document(store=nil)
metadocs.size > 1 ? metadocs.inject { |a, b| a + b }.make_immutable! : metadocs.first
end

private

def make_document(store=nil)
raise NoDefaultStoreError.new unless store ||= StrokeDB.default_store
@meta_initialization_procs.each {|proc| proc.call }.clear
Expand All @@ -237,7 +248,7 @@ def make_document(store=nil)
values[:meta] = Meta.document(store)
values[:name] ||= name.demodulize
values[:nsurl] ||= name.modulize.empty? ? Module.nsurl : name.modulize.constantize.nsurl
values[:uuid] ||= ::Util.sha1_uuid("meta:#{values[:nsurl]}##{values[:name]}") if values[:name]
values[:uuid] ||= Meta.make_uuid(values[:nsurl],values[:name]) if values[:name]

if meta_doc = find_meta_doc(values, store)
values[:version] = meta_doc.version
Expand Down
17 changes: 0 additions & 17 deletions spec/lib/strokedb/document/meta_meta_spec.rb
Expand Up @@ -13,23 +13,6 @@

end

describe "Meta meta instantiation" do

before(:each) do
# @store = mock("store")
# StrokeDB.stub!(:default_store).and_return(@store)
setup_default_store
Object.send!(:remove_const,'SomeName') if defined?(SomeName)
@meta = Meta.new(:name => "SomeName")
end

it "should create new meta module and bind it to name passed" do
@meta.should be_a_kind_of(Meta)
SomeName.should == @meta
end

end

describe "Meta meta instantiation with block specified" do

before(:each) do
Expand Down
32 changes: 29 additions & 3 deletions spec/lib/strokedb/document/meta_spec.rb
Expand Up @@ -32,7 +32,7 @@
new_doc = nil
2.times do |i|
Object.send!(:remove_const,'SomeName') if defined?(SomeName)
@meta = Meta.new(:name => "SomeName", :description => "Something")
SomeName = Meta.new(:description => "Something")
new_doc = SomeName.document
end
new_doc.uuid.should == doc.uuid
Expand Down Expand Up @@ -162,6 +162,33 @@
end
end


describe "Meta module without constant definition" do

before(:each) do
setup_default_store
setup_index
@some_name = Meta.new(:name => 'SomeName') do
def some
end
end
end

it "should not set respective constant" do
defined?(SomeName).should be_nil
end

it "should have its name constantizeable anyway" do
Meta.resolve_uuid_name("","SomeName").constantize.should == @some_name
end

it "should be loaded into document on its load" do
doc = @some_name.create!.reload
doc.should respond_to(:some)
end

end

describe "Meta module within no module" do

before(:each) do
Expand Down Expand Up @@ -254,7 +281,6 @@ module A
before(:each) do
setup_default_store
setup_index

Object.send!(:remove_const,'SomeName') if defined?(SomeName)
SomeName = Meta.new do
on_load do |obj|
Expand All @@ -271,7 +297,7 @@ module A
it "should receive this callback on document load" do
doc = SomeName.create!
Kernel.should_receive(:on_load_called).with(false)
SomeName.find(doc.uuid)
d = SomeName.find(doc.uuid)
end


Expand Down

0 comments on commit 591e7fe

Please sign in to comment.