grosser-concern 0.2.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/README.markdown ADDED
@@ -0,0 +1,79 @@
1
+ Seperation of concerns without meta-madness and namespace pollution.
2
+
3
+ Normal includes and extensions pollute the namespace and share private/protected.
4
+ With concern, everything stays in the Concern, can access the concerned and keep namespaced+private.
5
+
6
+ Install
7
+ =======
8
+ As Gem: ` sudo gem install grosser-concern -s http://gems.github.com `
9
+ Or as Rails plugin: ` script/plugins install git://github.com/grosser/concern.git `
10
+
11
+ Usage
12
+ =====
13
+ Normal usage:
14
+ # a.rb
15
+ require 'concern'
16
+ class A
17
+ concern 'a/acl'
18
+
19
+ def admin? ...
20
+ end
21
+
22
+ # a/acl.rb
23
+ class A::ACL < Concern
24
+ def can_access?(vault)
25
+ admin? and secret
26
+ end
27
+
28
+ private
29
+
30
+ def secrect ...
31
+ end
32
+
33
+ A.new.acl.can_access?(BankAccount)
34
+
35
+ Delegate usage:
36
+
37
+ class A
38
+ class Message
39
+ def write_message ...
40
+ def read_message ...
41
+ end
42
+
43
+ concern 'a/acl', :delegate => :true # all public
44
+ concern 'a/messages', :delegate => [:write_message]
45
+ end
46
+
47
+ A.new.can_access?(BankAccount)
48
+ A.new.write_message
49
+ A.new.message.read_message
50
+
51
+ Adding to concerned:
52
+ class A
53
+ class B < Concern
54
+ def initialize
55
+ super
56
+ @something = {}
57
+ end
58
+
59
+ def self.included(base)
60
+ base.class_eval do
61
+ test
62
+ end
63
+ end
64
+ end
65
+
66
+ def self.test
67
+ puts "it works"
68
+ end
69
+
70
+ concern 'a/b'
71
+ end
72
+
73
+ More examples can be found in [spec/examples](http://github.com/grosser/concern/tree/master/spec/examples)
74
+
75
+ Author
76
+ ======
77
+ [Michael Grosser](http://pragmatig.wordpress.com)
78
+ grosser.michael@gmail.com
79
+ Hereby placed under public domain, do what you want, just do not hold me accountable...
data/Rakefile.rb ADDED
@@ -0,0 +1,20 @@
1
+ desc "Run all specs in spec directory"
2
+ task :default do
3
+ options = "--colour --format progress --loadby --reverse"
4
+ files = FileList['spec/**/*_spec.rb']
5
+ system("spec #{options} #{files}")
6
+ end
7
+
8
+ begin
9
+ require 'jeweler'
10
+ project_name = 'concern'
11
+ Jeweler::Tasks.new do |gem|
12
+ gem.name = project_name
13
+ gem.description = gem.summary = "Seperation of concerns without meta-madness and namespace pollution"
14
+ gem.email = "grosser.michael@gmail.com"
15
+ gem.homepage = "http://github.com/grosser/#{project_name}"
16
+ gem.authors = ["Michael Grosser"]
17
+ end
18
+ rescue LoadError
19
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
20
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
data/concern.gemspec ADDED
@@ -0,0 +1,56 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{concern}
5
+ s.version = "0.2.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Michael Grosser"]
9
+ s.date = %q{2009-09-12}
10
+ s.description = %q{Seperation of concerns without meta-madness and namespace pollution}
11
+ s.email = %q{grosser.michael@gmail.com}
12
+ s.extra_rdoc_files = [
13
+ "README.markdown"
14
+ ]
15
+ s.files = [
16
+ "README.markdown",
17
+ "Rakefile.rb",
18
+ "VERSION",
19
+ "concern.gemspec",
20
+ "init.rb",
21
+ "lib/concern.rb",
22
+ "spec/concern_spec.rb",
23
+ "spec/examples/a/b.rb",
24
+ "spec/examples/adding.rb",
25
+ "spec/examples/delegate.rb",
26
+ "spec/examples/inline.rb",
27
+ "spec/examples/load.rb",
28
+ "spec/examples/parent_warning.rb",
29
+ "spec/examples/picky_delegate.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/grosser/concern}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.4}
35
+ s.summary = %q{Seperation of concerns without meta-madness and namespace pollution}
36
+ s.test_files = [
37
+ "spec/examples/adding.rb",
38
+ "spec/examples/picky_delegate.rb",
39
+ "spec/examples/inline.rb",
40
+ "spec/examples/load.rb",
41
+ "spec/examples/parent_warning.rb",
42
+ "spec/examples/delegate.rb",
43
+ "spec/examples/a/b.rb",
44
+ "spec/concern_spec.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ else
53
+ end
54
+ else
55
+ end
56
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ #only needed wen used as Rails plugin
2
+ require 'concern'
data/lib/concern.rb ADDED
@@ -0,0 +1,59 @@
1
+ class Concern
2
+ VERSION = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION'))
3
+
4
+ attr_accessor :concerned
5
+
6
+ def self.classify(lib)
7
+ lib.split('/').map{|part| part.capitalize }.join('::')
8
+ end
9
+ end
10
+
11
+ class Object
12
+ def self.concern(lib, options={})
13
+ # load delegate
14
+ lib = lib.to_s
15
+ klass = Concern.classify(lib)
16
+ begin
17
+ klass = eval(klass)
18
+ rescue
19
+ require lib
20
+ klass = eval(klass)
21
+ end
22
+
23
+ unless klass.instance_methods.map{|x|x.to_s}.include?('concerned=')
24
+ raise "A concern must always extend Concern"
25
+ end
26
+
27
+ # make accessor
28
+ accessor = lib.split('/').last.to_sym
29
+ eval <<-EOF
30
+ def #{accessor}
31
+ return @#{accessor} if @#{accessor}
32
+ @#{accessor} = #{klass}.new
33
+ @#{accessor}.concerned = self
34
+ @#{accessor}
35
+ end
36
+ EOF
37
+
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
41
+
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
49
+
50
+ methods.each do |method|
51
+ eval <<-EOF
52
+ def #{method}(*args)
53
+ #{accessor}.#{method}(*args)
54
+ end
55
+ EOF
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,25 @@
1
+ describe "Concern" do
2
+ it "loads the correct file" do
3
+ `ruby spec/examples/load.rb`.should == "hello"
4
+ end
5
+
6
+ it "can use already present class" do
7
+ `ruby spec/examples/inline.rb`.should == "inline"
8
+ end
9
+
10
+ it "can delegate" do
11
+ `ruby spec/examples/delegate.rb`.should == "hello"
12
+ end
13
+
14
+ it "can delegate some" do
15
+ `ruby spec/examples/picky_delegate.rb`.should == "hello"
16
+ end
17
+
18
+ it "add to parent" do
19
+ `ruby spec/examples/adding.rb`.should == "yepworld"
20
+ end
21
+
22
+ it "warns when parent is not Concern" do
23
+ `ruby spec/examples/parent_warning.rb`.should == "SUCCESS"
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ class A::B < Concern
2
+ def test
3
+ 'hello'
4
+ end
5
+
6
+ def test2
7
+ 'ohoh'
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ $LOAD_PATH << 'lib' << 'spec/examples'
2
+ require 'concern'
3
+
4
+ class A
5
+ class B < Concern
6
+ def initialize
7
+ super
8
+ @hello = 'world'
9
+ end
10
+
11
+ def hello
12
+ @hello
13
+ end
14
+
15
+ def self.included(base)
16
+ base.class_eval do
17
+ test
18
+ end
19
+ end
20
+ end
21
+
22
+ def self.test
23
+ print "yep"
24
+ end
25
+
26
+ concern 'a/b'
27
+ end
28
+
29
+ print A.new.b.hello
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH << 'lib' << 'spec/examples'
2
+ require 'concern'
3
+
4
+ class A
5
+ def xxx
6
+ 'xxx'
7
+ end
8
+ concern 'a/b', :delegate=>true
9
+ end
10
+
11
+ raise if A.new.send(:xxx) != 'xxx'
12
+ print A.new.test
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH << 'lib'
2
+ require 'concern'
3
+
4
+ class A
5
+ class B < Concern
6
+ def test
7
+ 'inline'
8
+ end
9
+ end
10
+ concern 'a/b'
11
+ end
12
+
13
+ print A.new.b.test
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH << 'lib' << 'spec/examples'
2
+ require 'concern'
3
+
4
+ class A
5
+ concern 'a/b'
6
+ end
7
+
8
+ print A.new.b.test
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH << 'lib' << 'spec/examples'
2
+ require 'concern'
3
+
4
+ class A
5
+ class B # < Concern
6
+ end
7
+
8
+ begin
9
+ concern 'a/b'
10
+ print 'FAIL'
11
+ rescue
12
+ raise unless $!.to_s =~ /extend Concern/
13
+ print 'SUCCESS'
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH << 'lib' << 'spec/examples'
2
+ require 'concern'
3
+ class A
4
+ concern 'a/b', :delegate=>[:test]
5
+ end
6
+
7
+ ok = begin
8
+ A.new.test2
9
+ false
10
+ rescue
11
+ true
12
+ end
13
+ raise unless ok
14
+ print A.new.test
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grosser-concern
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Grosser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-12 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Seperation of concerns without meta-madness and namespace pollution
17
+ email: grosser.michael@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - README.markdown
26
+ - Rakefile.rb
27
+ - VERSION
28
+ - concern.gemspec
29
+ - init.rb
30
+ - lib/concern.rb
31
+ - spec/concern_spec.rb
32
+ - spec/examples/a/b.rb
33
+ - spec/examples/adding.rb
34
+ - spec/examples/delegate.rb
35
+ - spec/examples/inline.rb
36
+ - spec/examples/load.rb
37
+ - spec/examples/parent_warning.rb
38
+ - spec/examples/picky_delegate.rb
39
+ has_rdoc: false
40
+ homepage: http://github.com/grosser/concern
41
+ licenses:
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Seperation of concerns without meta-madness and namespace pollution
66
+ test_files:
67
+ - spec/examples/adding.rb
68
+ - spec/examples/picky_delegate.rb
69
+ - spec/examples/inline.rb
70
+ - spec/examples/load.rb
71
+ - spec/examples/parent_warning.rb
72
+ - spec/examples/delegate.rb
73
+ - spec/examples/a/b.rb
74
+ - spec/concern_spec.rb