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 CHANGED
@@ -1 +1 @@
1
- 1.0.3
1
+ 1.1.0
data/lib/classy.rb CHANGED
@@ -1,3 +1,4 @@
1
- Dir.foreach( File.join( File.dirname(__FILE__), 'classy' ) ) do |entry|
2
- require "classy/#{entry}" if entry =~ /\.rb$/
1
+ path = File.join(File.dirname(__FILE__), 'classy')
2
+ Dir.foreach( path ) do |entry|
3
+ require "#{path}/#{entry}" if entry =~ /\.rb$/
3
4
  end
@@ -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
@@ -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.3
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-04 00:00:00 -05:00
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: []