display_case 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -32,7 +32,9 @@ Your exhibits will look something like this:
32
32
  # app/exhibits/league_exhibit.rb
33
33
 
34
34
  class LeagueExhibit < DisplayCase::Exhibit
35
- def self.applicable_to?(object)
35
+ # Note: the context parameter is new in the master branch, not yet released in the gem.
36
+ # If you get an argument error, that's why
37
+ def self.applicable_to?(object, context)
36
38
  object.class.name == 'League'
37
39
  end
38
40
 
@@ -0,0 +1,18 @@
1
+ require_relative 'exhibit'
2
+
3
+ module DisplayCase
4
+ class BasicExhibit < Exhibit
5
+ def to_partial_path
6
+ if __getobj__.respond_to?(:to_partial_path)
7
+ __getobj__.to_partial_path.dup
8
+ else
9
+ partialize_name(__getobj__.class.name)
10
+ end
11
+ end
12
+
13
+ def render(template)
14
+ template.render(:partial => to_partial_path, :object => self)
15
+ end
16
+ end
17
+ end
18
+
@@ -15,7 +15,7 @@ module DisplayCase
15
15
  # dynamically collected with the inherited callback. By default, this is false
16
16
  # and the list will be generated via the inherited callback.
17
17
  attr_accessor :explicit
18
-
18
+
19
19
  # An Array of strings specifying locations that should be searched for
20
20
  # exhibit classes and definitions. By default, "/app/exhibits" will be searched and
21
21
  # existing file will be loaded.
@@ -32,7 +32,7 @@ module DisplayCase
32
32
  end
33
33
 
34
34
  def exhibits
35
- [DisplayCase::Exhibit::Exhibited,DisplayCase::EnumerableExhibit] + @exhibits
35
+ [DisplayCase::Exhibit::Exhibited,DisplayCase::BasicExhibit,DisplayCase::EnumerableExhibit] + @exhibits
36
36
  end
37
37
 
38
38
  def exhibits=(val)
@@ -41,4 +41,4 @@ module DisplayCase
41
41
  end
42
42
 
43
43
  configure {}
44
- end
44
+ end
@@ -4,7 +4,7 @@ module DisplayCase
4
4
  class EnumerableExhibit < Exhibit
5
5
  include Enumerable
6
6
 
7
- def self.applicable_to?(object)
7
+ def self.applicable_to?(object, context=nil)
8
8
  # ActiveRecord::Relation, surprisingly, is not Enumerable. But it
9
9
  # behaves sufficiently similarly for our purposes.
10
10
  object_is_any_of?(object, 'Enumerable', 'ActiveRecord::Relation')
@@ -34,9 +34,10 @@ module DisplayCase
34
34
  end
35
35
 
36
36
  def each(*)
37
- super do |e|
38
- yield exhibit(e)
39
- end
37
+ __getobj__.map do |e|
38
+ yield exhibit(e) if block_given?
39
+ exhibit(e)
40
+ end.each
40
41
  end
41
42
 
42
43
  # `render '...', :collection => self` will call #to_ary on this
@@ -1,12 +1,14 @@
1
1
  require 'delegate'
2
2
  require 'active_support/core_ext'
3
- require 'display_case/railtie' if defined?(Rails)
3
+ require 'display_case/railtie' if defined?(::Rails)
4
4
  require_relative 'configuration'
5
+ require_relative 'is_a_class_comparator'
6
+ require_relative 'name_class_comparator'
5
7
 
6
8
  module DisplayCase
7
9
  class Exhibit < SimpleDelegator
8
10
  @@exhibits = []
9
-
11
+
10
12
  def self.exhibits
11
13
  if DisplayCase.configuration.explicit?
12
14
  DisplayCase.configuration.exhibits
@@ -14,36 +16,36 @@ module DisplayCase
14
16
  @@exhibits
15
17
  end
16
18
  end
17
-
19
+
18
20
  def self.inherited(child)
19
21
  @@exhibits << child
20
22
  end
21
23
 
22
- def self.exhibit(object, context)
24
+ def self.exhibit(object, context=nil)
23
25
  return object if exhibited_object?(object)
24
- if defined? Rails
25
- Rails.logger.debug "Registered exhibits: #{@@exhibits}"
26
- Rails.logger.debug "Exhibiting #{object.inspect}"
27
- Rails.logger.debug "Exhibit context: #{context}"
26
+ if defined? ::Rails
27
+ ::Rails.logger.debug "Registered exhibits: #{@@exhibits}"
28
+ ::Rails.logger.debug "Exhibiting #{object.inspect}"
29
+ ::Rails.logger.debug "Exhibit context: #{context}"
28
30
  end
29
-
30
- object = Exhibited.new(object, context)
31
+
32
+ object = BasicExhibit.new(Exhibited.new(object, context), context)
31
33
  exhibits.inject(object) do |object, exhibit_class|
32
34
  exhibit_class.exhibit_if_applicable(object, context)
33
35
  end.tap do |obj|
34
- Rails.logger.debug "Exhibits applied: #{obj.inspect_exhibits}" if defined? Rails
36
+ ::Rails.logger.debug "Exhibits applied: #{obj.inspect_exhibits}" if defined? ::Rails
35
37
  end
36
38
  end
37
39
 
38
40
  def self.exhibit_if_applicable(object, context)
39
- if applicable_to?(object)
41
+ if applicable_to?(object, context)
40
42
  new(object, context)
41
43
  else
42
44
  object
43
45
  end
44
46
  end
45
47
 
46
- def self.applicable_to?(object)
48
+ def self.applicable_to?(object, context=nil)
47
49
  false
48
50
  end
49
51
 
@@ -60,18 +62,25 @@ module DisplayCase
60
62
  end
61
63
  private_class_method :exhibit_query
62
64
 
65
+ def self.class_comparator
66
+ @@class_comparator ||= begin
67
+ comparator = nil
68
+
69
+ if defined? ::Rails
70
+ config = ::Rails.respond_to?(:config) ? ::Rails.config : ::Rails.application.config
71
+ comparator = NameClassComparator.new unless config.cache_classes
72
+ end
73
+
74
+ comparator || IsAClassComparator.new
75
+ end
76
+ end
77
+
63
78
  # A helper for matching models to classes/modules, intended for use
64
79
  # in .applicable_to?.
65
80
  def self.object_is_any_of?(object, *classes)
66
- # What with Rails development mode reloading making class matching
67
- # unreliable, plus wanting to avoid adding dependencies to
68
- # external class definitions if we can avoid it, we just match
69
- # against class/module name strings rather than the actual class
70
- # objects.
71
-
72
- # Note that '&' is the set intersection operator for Arrays.
73
- (classes.map(&:to_s) & object.class.ancestors.map(&:name)).any?
81
+ self.class_comparator.call(object, *classes)
74
82
  end
83
+
75
84
  private_class_method :object_is_any_of?
76
85
 
77
86
  attr_reader :context
@@ -85,25 +94,26 @@ module DisplayCase
85
94
  def class
86
95
  __getobj__.class
87
96
  end
88
-
89
- def exhibit(model)
90
- Exhibit.exhibit(model, context)
97
+
98
+ alias_method :__kind_of__?, :kind_of?
99
+ def kind_of?(klass)
100
+ __getobj__.kind_of?(klass)
91
101
  end
92
-
93
- def to_partial_path
94
- if __getobj__.respond_to?(:to_partial_path)
95
- __getobj__.to_partial_path.dup
96
- else
97
- partialize_name(__getobj__.class.name)
98
- end
102
+
103
+ alias_method :__is_a__?, :is_a?
104
+ alias_method :is_a?, :kind_of?
105
+
106
+ alias_method :__instance_of__?, :instance_of?
107
+ def instance_of?(klass)
108
+ __getobj__.instance_of?(klass)
99
109
  end
100
110
 
101
- def render(template)
102
- template.render(:partial => to_partial_path, :object => self)
111
+ def exhibit(model)
112
+ Exhibit.exhibit(model, context)
103
113
  end
104
114
 
105
115
  def exhibit_chain
106
- inner_exhibits = defined?(super) ? super : []
116
+ inner_exhibits = __getobj__.respond_to?(:exhibit_chain) ? __getobj__.exhibit_chain : []
107
117
  [__class__] + inner_exhibits
108
118
  end
109
119
 
@@ -137,4 +147,4 @@ module DisplayCase
137
147
  "/#{name.underscore.pluralize}/#{name.demodulize.underscore}"
138
148
  end
139
149
  end
140
- end
150
+ end
@@ -0,0 +1,38 @@
1
+ module DisplayCase
2
+ class IsAClassComparator
3
+ def call(object, *classes)
4
+ classes.any?{|klass| object.is_a?(class_object(klass))}
5
+ end
6
+
7
+ private
8
+
9
+ # A simple memoizing class name tracker
10
+ class ClassTracker
11
+ def initialize
12
+ @context = Object
13
+ @data = Hash.new {|h, k| h[k] = constantize(k)}
14
+ end
15
+
16
+ def class_for(class_name)
17
+ @data[class_name]
18
+ end
19
+
20
+ def constantize(class_name)
21
+ return class_name if Module === class_name
22
+ class_name.to_s.split('::').inject(@context){|context, name|
23
+ context.const_get(name)
24
+ }
25
+ end
26
+ end
27
+
28
+ # holds a reference to the tracker
29
+ def class_tracker
30
+ @class_tracker ||= ClassTracker.new
31
+ end
32
+
33
+ # helper method for object_is_any_of to use
34
+ def class_object(cls)
35
+ class_tracker.class_for(cls)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ module DisplayCase
2
+ # What with Rails development mode reloading making class matching
3
+ # unreliable, plus wanting to avoid adding dependencies to external
4
+ # class definitions if we can avoid it, this class just matches
5
+ # against class/module name strings rather than the actual class
6
+ # objects.
7
+ class NameClassComparator
8
+ def call(object, *classes)
9
+ # Note that '&' is the set intersection operator for Arrays.
10
+ (classes.map(&:to_s) & object.class.ancestors.map(&:name)).any?
11
+ end
12
+ end
13
+ end
data/lib/display_case.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require_relative 'display_case/configuration'
2
2
  require_relative 'display_case/exhibit'
3
3
  require_relative 'display_case/enumerable_exhibit'
4
+ require_relative 'display_case/basic_exhibit'
4
5
  require_relative 'display_case/exhibits_helper'
5
6
  require_relative 'display_case/find_definitions'
6
7
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: display_case
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-15 00:00:00.000000000 Z
12
+ date: 2013-02-14 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: An implementation of the Exhibit pattern, as described in Objects on
15
15
  Rails
@@ -19,11 +19,14 @@ executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
+ - lib/display_case/basic_exhibit.rb
22
23
  - lib/display_case/configuration.rb
23
24
  - lib/display_case/enumerable_exhibit.rb
24
25
  - lib/display_case/exhibit.rb
25
26
  - lib/display_case/exhibits_helper.rb
26
27
  - lib/display_case/find_definitions.rb
28
+ - lib/display_case/is_a_class_comparator.rb
29
+ - lib/display_case/name_class_comparator.rb
27
30
  - lib/display_case/railtie.rb
28
31
  - lib/display_case.rb
29
32
  - LICENSE
@@ -48,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
51
  version: '0'
49
52
  requirements: []
50
53
  rubyforge_project:
51
- rubygems_version: 1.8.10
54
+ rubygems_version: 1.8.8
52
55
  signing_key:
53
56
  specification_version: 3
54
57
  summary: An implementation of the Exhibit pattern, as described in Objects on Rails