grosser-concern 0.2.0

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