classy 1.0.3 → 1.1.0
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/VERSION +1 -1
- data/lib/classy.rb +3 -2
- data/lib/classy/templatable.rb +61 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/templatable_spec.rb +76 -0
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
data/lib/classy.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
module Templatable
|
2
|
+
|
3
|
+
# A hash to track templatable variables that have been locally set.
|
4
|
+
# (Required to distinguish between variables explicitly set to nil and those
|
5
|
+
# left as nil by default.)
|
6
|
+
#
|
7
|
+
@@ever_been_set = Hash.new { |hash, key| hash[key] = {} }
|
8
|
+
|
9
|
+
def templatable_attr (*symbols)
|
10
|
+
symbols.each do |symbol|
|
11
|
+
# define the instance setter method
|
12
|
+
#
|
13
|
+
define_method("#{symbol}=".to_sym) do |value|
|
14
|
+
instance_variable_set("@#{symbol}", value)
|
15
|
+
@@ever_been_set[self][symbol] = true
|
16
|
+
end
|
17
|
+
|
18
|
+
# define the instance getter method
|
19
|
+
#
|
20
|
+
define_method(symbol) do
|
21
|
+
if @@ever_been_set[self][symbol]
|
22
|
+
return instance_variable_get("@#{symbol}")
|
23
|
+
elsif self.class.class_variable_defined?("@@#{symbol}")
|
24
|
+
return self.class.class_exec { class_variable_get("@@#{symbol}") }
|
25
|
+
else
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class_exec do
|
31
|
+
# define the class setter method
|
32
|
+
#
|
33
|
+
# We have to use this send hack, since define_method is private.
|
34
|
+
#
|
35
|
+
self.class.send(:define_method, "#{symbol}=".to_sym) do |value|
|
36
|
+
class_variable_set("@@#{symbol}", value)
|
37
|
+
end
|
38
|
+
|
39
|
+
# define the class getter/setter method
|
40
|
+
#
|
41
|
+
# We want to be able to call this like a dsl as a setter, or like a
|
42
|
+
# class method as a getter, so we need variable arity, which
|
43
|
+
# define_method doesn't support. In order to use the standard `def`
|
44
|
+
# with variable arity, eval'ing a string seems to be the only option.
|
45
|
+
#
|
46
|
+
# Oh man would I love for somebody to submit a patch to do this in a
|
47
|
+
# less horrible way.
|
48
|
+
#
|
49
|
+
self.class.class_eval "
|
50
|
+
def #{symbol} (value = nil)
|
51
|
+
if value
|
52
|
+
class_variable_set(\"@@#{symbol}\", value)
|
53
|
+
end
|
54
|
+
class_variable_get(\"@@#{symbol}\") if class_variable_defined?(\"@@#{symbol}\")
|
55
|
+
end
|
56
|
+
"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,3 +7,10 @@ require 'spec/autorun'
|
|
7
7
|
Spec::Runner.configure do |config|
|
8
8
|
|
9
9
|
end
|
10
|
+
|
11
|
+
# Doesn't work for anything inside a module (eg, if you try to remove
|
12
|
+
# Testify::Framework::RSpec this will totally blow up).
|
13
|
+
def destroy_class ( klass )
|
14
|
+
klass = klass.name.to_s if klass.kind_of? Class
|
15
|
+
Object.class_exec { remove_const klass } if Object.const_defined? klass
|
16
|
+
end
|
data/spec/templatable_spec.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "Templatable" do
|
4
|
+
|
5
|
+
before do
|
6
|
+
destroy_class(Widget) if defined?(Widget)
|
7
|
+
class Widget
|
8
|
+
extend Templatable
|
9
|
+
templatable_attr :temperature, :awesomeness
|
10
|
+
end
|
11
|
+
|
12
|
+
Widget.awesomeness = :total
|
13
|
+
|
14
|
+
@doodad = Widget.new
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow default values to be set as an assignment" do
|
18
|
+
Widget.temperature = :cool
|
19
|
+
Widget.temperature.should equal :cool
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should allow default values to be via a dsl" do
|
23
|
+
class Widget
|
24
|
+
temperature :hot!
|
25
|
+
end
|
26
|
+
Widget.temperature.should equal :hot!
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return the default value from the class when set" do
|
30
|
+
Widget.awesomeness.should equal :total
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return nil from the class when unset" do
|
34
|
+
Widget.temperature.should be_nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return the default value from an instance when set and not overridden" do
|
38
|
+
@doodad.awesomeness.should equal :total
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return nil from an instance when unset and not overrideen" do
|
42
|
+
@doodad.temperature.should be_nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should allow instances to override the default values" do
|
46
|
+
@doodad.awesomeness = :sorta_i_guess
|
47
|
+
@doodad.awesomeness.should equal :sorta_i_guess
|
48
|
+
end
|
49
|
+
|
50
|
+
it "shouldn't affect other instances when overriding a value" do
|
51
|
+
@whatsit = Widget.new
|
52
|
+
@whatsit.awesomeness = :locally
|
53
|
+
|
54
|
+
@doodad.awesomeness.should equal(:total)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "shouldn't affect other Templatable classes" do
|
58
|
+
destroy_class(Pony) if defined?(Pony)
|
59
|
+
class Pony
|
60
|
+
extend Templatable
|
61
|
+
templatable_attr :name, :awesomeness
|
62
|
+
end
|
63
|
+
sugar = Pony.new # You get a pony!
|
64
|
+
|
65
|
+
Pony.awesomeness.should be_nil
|
66
|
+
sugar.awesomeness.should be_nil
|
67
|
+
|
68
|
+
Pony.awesomeness = :omg
|
69
|
+
Pony.awesomeness.should equal(:omg)
|
70
|
+
sugar.awesomeness.should equal(:omg)
|
71
|
+
|
72
|
+
sugar.awesomeness = :meh # Apparently, you get a bad pony.
|
73
|
+
sugar.awesomeness.should equal(:meh)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: classy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Hyland
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-12 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -41,10 +41,12 @@ files:
|
|
41
41
|
- lib/classy.rb
|
42
42
|
- lib/classy/aliasable.rb
|
43
43
|
- lib/classy/subclass_aware.rb
|
44
|
+
- lib/classy/templatable.rb
|
44
45
|
- spec/aliasable_spec.rb
|
45
46
|
- spec/spec.opts
|
46
47
|
- spec/spec_helper.rb
|
47
48
|
- spec/subclass_aware_spec.rb
|
49
|
+
- spec/templatable_spec.rb
|
48
50
|
has_rdoc: true
|
49
51
|
homepage: http://github.com/djspinmonkey/classy
|
50
52
|
licenses: []
|