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 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: []