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 +79 -0
- data/Rakefile.rb +20 -0
- data/VERSION +1 -0
- data/concern.gemspec +56 -0
- data/init.rb +2 -0
- data/lib/concern.rb +59 -0
- data/spec/concern_spec.rb +25 -0
- data/spec/examples/a/b.rb +9 -0
- data/spec/examples/adding.rb +29 -0
- data/spec/examples/delegate.rb +12 -0
- data/spec/examples/inline.rb +13 -0
- data/spec/examples/load.rb +8 -0
- data/spec/examples/parent_warning.rb +15 -0
- data/spec/examples/picky_delegate.rb +14 -0
- metadata +74 -0
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
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,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
|
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
|