concern 0.2.1 → 0.2.2

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/Readme.md CHANGED
@@ -67,8 +67,12 @@ Adding to the concerned, e.g. validations/associations/scopes etc.
67
67
 
68
68
  More examples can be found in [spec/examples](http://github.com/grosser/concern/tree/master/spec/examples)
69
69
 
70
- Author
71
- ======
70
+ Authors
71
+ =======
72
+
73
+ ### [Contributors](http://github.com/grosser/concern/contributors)
74
+ - [Colin Curtin](http://github.com/perplexes)
75
+
72
76
  [Michael Grosser](http://grosser.it)
73
77
  grosser.michael@gmail.com
74
- Hereby placed under public domain, do what you want, just do not hold me accountable...
78
+ Hereby placed under public domain, do what you want, just do not hold me accountable...
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.2.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{concern}
8
- s.version = "0.2.1"
8
+ s.version = "0.2.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Michael Grosser"]
12
- s.date = %q{2010-10-19}
12
+ s.date = %q{2010-10-29}
13
13
  s.description = %q{Seperation of concerns without meta-madness and namespace pollution}
14
14
  s.email = %q{grosser.michael@gmail.com}
15
15
  s.files = [
@@ -23,13 +23,15 @@ Gem::Specification.new do |s|
23
23
  "spec/examples/a/b.rb",
24
24
  "spec/examples/a/bc_def_gh.rb",
25
25
  "spec/examples/adding.rb",
26
+ "spec/examples/blocks.rb",
26
27
  "spec/examples/complex_inline.rb",
27
28
  "spec/examples/complex_require.rb",
28
29
  "spec/examples/delegate.rb",
29
30
  "spec/examples/inline.rb",
30
31
  "spec/examples/load.rb",
31
32
  "spec/examples/parent_warning.rb",
32
- "spec/examples/picky_delegate.rb"
33
+ "spec/examples/picky_delegate.rb",
34
+ "spec/examples/pollution.rb"
33
35
  ]
34
36
  s.homepage = %q{http://github.com/grosser/concern}
35
37
  s.rdoc_options = ["--charset=UTF-8"]
@@ -42,10 +44,12 @@ Gem::Specification.new do |s|
42
44
  "spec/examples/complex_inline.rb",
43
45
  "spec/examples/parent_warning.rb",
44
46
  "spec/examples/adding.rb",
47
+ "spec/examples/pollution.rb",
45
48
  "spec/examples/complex_require.rb",
46
49
  "spec/examples/load.rb",
47
50
  "spec/examples/a/b.rb",
48
51
  "spec/examples/a/bc_def_gh.rb",
52
+ "spec/examples/blocks.rb",
49
53
  "spec/examples/delegate.rb",
50
54
  "spec/examples/inline.rb"
51
55
  ]
@@ -6,11 +6,8 @@ class Concern
6
6
  def self.classify(lib)
7
7
  lib.split('/').map{|part| part.gsub(/(?:^|_)(.)/){ $1.upcase } }.join('::')
8
8
  end
9
- end
10
9
 
11
- class Object
12
- def self.concern(lib, options={})
13
- # load delegate
10
+ def self.class_from_lib(lib)
14
11
  lib = lib.to_s
15
12
  klass = Concern.classify(lib)
16
13
  begin
@@ -23,37 +20,49 @@ class Object
23
20
  unless klass.instance_methods.map{|x|x.to_s}.include?('concerned=')
24
21
  raise "A concern must always extend Concern"
25
22
  end
23
+ klass
24
+ end
26
25
 
27
- # make accessor
28
- accessor = lib.split('/').last.to_sym
29
- eval <<-EOF
26
+ def self.add_accessor_for_concern(concerned, accessor, concern)
27
+ concerned.class_eval <<-EOF, __FILE__, __LINE__
30
28
  def #{accessor}
31
29
  return @#{accessor} if @#{accessor}
32
- @#{accessor} = #{klass}.new
30
+ @#{accessor} = #{concern}.new
33
31
  @#{accessor}.concerned = self
34
32
  @#{accessor}
35
33
  end
36
34
  EOF
35
+ end
36
+
37
+ module ClassMethods
38
+ def concern(lib, options={})
39
+ concern = Concern.class_from_lib(lib)
40
+ accessor = lib.split('/').last.to_sym
37
41
 
38
- # call included
39
- base = eval(name) #self.class is always Class, but name is class that called concern
40
- klass.included(base) if klass.respond_to? :included
42
+ Concern.add_accessor_for_concern(self, accessor, concern)
41
43
 
42
- # delegate methods
43
- if options[:delegate]
44
- methods = if options[:delegate].is_a?(Array)
45
- options[:delegate]
46
- else
47
- klass.public_instance_methods(false)
48
- end
44
+ # tell the concern it was included
45
+ concerned = eval(name) #self.class is always Class, but name is class that called concern
46
+ concern.included(concerned) if concern.respond_to? :included
49
47
 
50
- methods.each do |method|
51
- eval <<-EOF
52
- def #{method}(*args)
53
- #{accessor}.#{method}(*args)
54
- end
55
- EOF
48
+ # delegate methods calls to the concern
49
+ if options[:delegate]
50
+ methods_to_delegate = if options[:delegate].is_a?(Array)
51
+ options[:delegate]
52
+ else
53
+ concern.public_instance_methods(false)
54
+ end
55
+
56
+ methods_to_delegate.each do |method|
57
+ class_eval <<-EOF, __FILE__, __LINE__
58
+ def #{method}(*args, &block)
59
+ #{accessor}.send(:#{method}, *args, &block)
60
+ end
61
+ EOF
62
+ end
56
63
  end
57
64
  end
58
65
  end
59
- end
66
+ end
67
+
68
+ Object.send(:extend, Concern::ClassMethods)
@@ -30,4 +30,12 @@ describe "Concern" do
30
30
  it "warns when parent is not Concern" do
31
31
  `ruby spec/examples/parent_warning.rb`.should == "SUCCESS"
32
32
  end
33
+
34
+ it "shouldn't pollute the global namespace" do
35
+ `ruby spec/examples/pollution.rb`.should == "SUCCESS"
36
+ end
37
+
38
+ it "should delegate blocks" do
39
+ `ruby spec/examples/blocks.rb`.should == "SUCCESS"
40
+ end
33
41
  end
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH << 'lib'
2
+ require 'concern'
3
+
4
+ class A
5
+ class B < Concern
6
+ def test
7
+ yield
8
+ end
9
+ end
10
+ concern 'a/b', :delegate => [:test]
11
+ end
12
+
13
+ print A.new.test{ "SUCCESS" }
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH << 'lib'
2
+ require 'concern'
3
+
4
+ class A
5
+ class B < Concern
6
+ def random_method_name
7
+ end
8
+ end
9
+ concern 'a/b', :delegate => [:random_method_name]
10
+ end
11
+
12
+ class C
13
+ class D < Concern
14
+ def random_method_name2
15
+ end
16
+ end
17
+ concern 'c/d', :delegate => true
18
+ end
19
+
20
+ if Object.instance_methods.include?("random_method_name") && Object.instance_methods.include?("random_method_name2")
21
+ print "FAIL"
22
+ else
23
+ print "SUCCESS"
24
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 1
9
- version: 0.2.1
8
+ - 2
9
+ version: 0.2.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Michael Grosser
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-19 00:00:00 +02:00
17
+ date: 2010-10-29 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -37,6 +37,7 @@ files:
37
37
  - spec/examples/a/b.rb
38
38
  - spec/examples/a/bc_def_gh.rb
39
39
  - spec/examples/adding.rb
40
+ - spec/examples/blocks.rb
40
41
  - spec/examples/complex_inline.rb
41
42
  - spec/examples/complex_require.rb
42
43
  - spec/examples/delegate.rb
@@ -44,6 +45,7 @@ files:
44
45
  - spec/examples/load.rb
45
46
  - spec/examples/parent_warning.rb
46
47
  - spec/examples/picky_delegate.rb
48
+ - spec/examples/pollution.rb
47
49
  has_rdoc: true
48
50
  homepage: http://github.com/grosser/concern
49
51
  licenses: []
@@ -80,9 +82,11 @@ test_files:
80
82
  - spec/examples/complex_inline.rb
81
83
  - spec/examples/parent_warning.rb
82
84
  - spec/examples/adding.rb
85
+ - spec/examples/pollution.rb
83
86
  - spec/examples/complex_require.rb
84
87
  - spec/examples/load.rb
85
88
  - spec/examples/a/b.rb
86
89
  - spec/examples/a/bc_def_gh.rb
90
+ - spec/examples/blocks.rb
87
91
  - spec/examples/delegate.rb
88
92
  - spec/examples/inline.rb