classy 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|