display_case 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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