concern 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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