modularity 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  doc
2
2
  pkg
3
3
  *.gem
4
+ .idea
5
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -1,104 +1,106 @@
1
- = modularity - Traits and partial classes for Ruby
2
-
3
- Modularity provides traits and partial classes for Ruby.
4
- This lets you organize large models into multiple source files.
5
- It also allows very simple definition of meta-programming macros,
6
- as you might now from <tt>acts_as_something</tt> type of plugins,
7
- or the macros Rails provides for your models.
8
-
9
- Modularity traits are to your models what partials are for your Rails views.
10
-
11
- == Example 1: Splitting a model into multiple source files
12
-
13
- Models are often concerned with multiple themes like "authentication", "contact info" or "permissions", each requiring
14
- a couple of validations and callbacks here, and some method there. Modularity lets you organize your model into multiple
15
- partial classes, so each file can deal with a single aspect of your model:
16
-
17
- # app/models/user.rb
18
- class User < ActiveRecord::Base
19
- does "user/authentication"
20
- does "user/address"
21
- end
22
-
23
- # app/models/user/authentication_trait.rb
24
- module User::AuthenticationTrait
25
- as_trait do
26
- # methods, validations, etc. regarding usernames and passwords go here
27
- end
28
- end
29
-
30
- # app/models/user/permissions_trait.rb
31
- module User::PermissionsTrait
32
- as_trait do
33
- # methods, validations, etc. regarding contact information go here
34
- end
35
- end
36
-
37
- == Example 2: Easy meta-programming macros
38
-
39
- Ruby allows you to construct classes using meta-programming macros like <tt>acts_as_tree</tt> or <tt>has_many :items</tt>.
40
- These macros will add methods, callbacks, etc. to the calling class. Hoever, right now Ruby (and Rails) makes it awkward to define
41
- such macros in your project as part of your application domain.
42
-
43
- Modularity allows you to extract common behaviour into reusable macros by defining traits with parameters. Your macros can live in your
44
- application, allowing you to express your application domain in both classes and macros.
45
-
46
- Here is an example of a <tt>strip_field</tt> macro, which created setter methods that remove leading and trailing whitespace from newly assigned values:
47
-
48
- # app/models/article.rb
49
- class Article
50
- does "strip_fields", :name, :brand
51
- end
52
-
53
- # app/models/shared/strip_fields_trait.rb
54
- module StripFieldsTrait
55
- as_trait do |*fields|
56
- fields.each do |field|
57
- define_method("#{field}=") do |value|
58
- self[field] = value.strip
59
- end
60
- end
61
- end
62
- end
63
-
64
- We like to add <tt>app/models/shared</tt> and <tt>app/controllers/shared</tt> to the load paths of our Rails projects. These are great places to store macros
65
- that are re-used from multiple classes.
66
-
67
- == Example 3: Mixins with class methods
68
-
69
- Using a module to add both instance methods and class methods is {very awkward}[http://redcorundum.blogspot.com/2006/06/mixing-in-class-methods.html].
70
- Modularity does away with the clutter and lets you say this:
71
-
72
- # app/models/model.rb
73
- class Model
74
- does "mixin"
75
- end
76
-
77
- # app/models/mixin_trait.rb
78
- module MixinTrait
79
- as_trait do
80
- def instance_method
81
- # ...
82
- end
83
- def self.class_method
84
- # ..
85
- end
86
- end
87
-
88
- <tt>private</tt> and <tt>protected</tt> will also work as expected when defining a trait.
89
-
90
- == Installation
91
-
92
- sudo gem sources -a http://gemcutter.org
93
- sudo gem install modularity
94
-
95
- == Dependencies
96
-
97
- Modularity requires Ruby 1.8.7. Earlier versions are missing <tt>class_exec</tt>. You might be able to hack in <tt>class_exec</tt>
98
- using {this}[http://github.com/brynary/rspec/blob/f80d61a399b34f58084a378c85a43a95ff484619/lib/spec/extensions/instance_exec.rb] as a guide, but it's not pretty.
99
-
100
- == Credits
101
-
102
- Henning Koch
103
-
104
- {www.makandra.de}[http://www.makandra.de/]
1
+ = modularity - Traits and partial classes for Ruby
2
+
3
+ Modularity provides traits and partial classes for Ruby.
4
+ This lets you organize large models into multiple source files.
5
+ It also allows very simple definition of meta-programming macros,
6
+ as you might now from <tt>acts_as_something</tt> type of plugins,
7
+ or the macros Rails provides for your models.
8
+
9
+ Modularity traits are to your models what partials are for your Rails views.
10
+
11
+ == Example 1: Splitting a model into multiple source files
12
+
13
+ Models are often concerned with multiple themes like "authentication", "contact info" or "permissions", each requiring
14
+ a couple of validations and callbacks here, and some method there. Modularity lets you organize your model into multiple
15
+ partial classes, so each file can deal with a single aspect of your model:
16
+
17
+ # app/models/user.rb
18
+ class User < ActiveRecord::Base
19
+ does "user/authentication"
20
+ does "user/address"
21
+ end
22
+
23
+ # app/models/user/authentication_trait.rb
24
+ module User::AuthenticationTrait
25
+ as_trait do
26
+ # methods, validations, etc. regarding usernames and passwords go here
27
+ end
28
+ end
29
+
30
+ # app/models/user/permissions_trait.rb
31
+ module User::PermissionsTrait
32
+ as_trait do
33
+ # methods, validations, etc. regarding contact information go here
34
+ end
35
+ end
36
+
37
+ == Example 2: Easy meta-programming macros
38
+
39
+ Ruby allows you to construct classes using meta-programming macros like <tt>acts_as_tree</tt> or <tt>has_many :items</tt>.
40
+ These macros will add methods, callbacks, etc. to the calling class. Hoever, right now Ruby (and Rails) makes it awkward to define
41
+ such macros in your project as part of your application domain.
42
+
43
+ Modularity allows you to extract common behaviour into reusable macros by defining traits with parameters. Your macros can live in your
44
+ application, allowing you to express your application domain in both classes and macros.
45
+
46
+ Here is an example of a <tt>strip_field</tt> macro, which created setter methods that remove leading and trailing whitespace from newly assigned values:
47
+
48
+ # app/models/article.rb
49
+ class Article
50
+ does "strip_fields", :name, :brand
51
+ end
52
+
53
+ # app/models/shared/strip_fields_trait.rb
54
+ module StripFieldsTrait
55
+ as_trait do |*fields|
56
+ fields.each do |field|
57
+ define_method("#{field}=") do |value|
58
+ self[field] = value.strip
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ We like to add <tt>app/models/shared</tt> and <tt>app/controllers/shared</tt> to the load paths of our Rails projects. These are great places to store macros
65
+ that are re-used from multiple classes.
66
+
67
+ == Example 3: Mixins with class methods
68
+
69
+ Using a module to add both instance methods and class methods is {very awkward}[http://redcorundum.blogspot.com/2006/06/mixing-in-class-methods.html].
70
+ Modularity does away with the clutter and lets you say this:
71
+
72
+ # app/models/model.rb
73
+ class Model
74
+ does "mixin"
75
+ end
76
+
77
+ # app/models/mixin_trait.rb
78
+ module MixinTrait
79
+ as_trait do
80
+ def instance_method
81
+ # ...
82
+ end
83
+ def self.class_method
84
+ # ..
85
+ end
86
+ end
87
+
88
+ <tt>private</tt> and <tt>protected</tt> will also work as expected when defining a trait.
89
+
90
+ == Installation
91
+
92
+ sudo gem install modularity
93
+
94
+
95
+ == Note if you're still on Ruby 1.8.6
96
+
97
+ Modularity requires Ruby 1.8.7. Earlier versions are missing <tt>class_exec</tt>. You might be able to hack in <tt>class_exec</tt>
98
+ using {this}[http://github.com/brynary/rspec/blob/f80d61a399b34f58084a378c85a43a95ff484619/lib/spec/extensions/instance_exec.rb] as a guide, but it's not pretty.
99
+
100
+ == Credits
101
+
102
+ Henning Koch
103
+
104
+ {makandra.com}[http://makandra.com/]
105
+
106
+ {gem-session.com}[http://gem-session.com/]
data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'rake'
2
- # require 'rake/testtask'
3
- require 'rake/rdoctask'
4
2
  require 'spec/rake/spectask'
3
+ require 'bundler/gem_tasks'
5
4
 
6
5
  desc 'Default: Run all specs.'
7
6
  task :default => :spec
@@ -11,27 +10,3 @@ Spec::Rake::SpecTask.new() do |t|
11
10
  t.spec_opts = ['--options', "\"spec/spec.opts\""]
12
11
  t.spec_files = FileList['spec/**/*_spec.rb']
13
12
  end
14
-
15
- desc 'Generate documentation for the modularity gem'
16
- Rake::RDocTask.new(:rdoc) do |rdoc|
17
- rdoc.rdoc_dir = 'rdoc'
18
- rdoc.title = 'modularity'
19
- rdoc.options << '--line-numbers' << '--inline-source'
20
- rdoc.rdoc_files.include('README')
21
- rdoc.rdoc_files.include('lib/**/*.rb')
22
- end
23
-
24
- begin
25
- require 'jeweler'
26
- Jeweler::Tasks.new do |gemspec|
27
- gemspec.name = "modularity"
28
- gemspec.summary = "Traits and partial classes for Ruby"
29
- gemspec.email = "github@makandra.de"
30
- gemspec.homepage = "http://github.com/makandra/modularity"
31
- gemspec.description = "Traits and partial classes for Ruby"
32
- gemspec.authors = ["Henning Koch"]
33
- end
34
- rescue LoadError
35
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
36
- end
37
-
@@ -13,7 +13,25 @@ module Modularity
13
13
  end
14
14
  end
15
15
 
16
- # File activesupport/lib/active_support/inflector.rb, line 355
16
+
17
+ if Module.method(:const_get).arity == 1
18
+ # Tries to find a constant with the name specified in the argument string:
19
+ #
20
+ # "Module".constantize # => Module
21
+ # "Test::Unit".constantize # => Test::Unit
22
+ #
23
+ # The name is assumed to be the one of a top-level constant, no matter whether
24
+ # it starts with "::" or not. No lexical context is taken into account:
25
+ #
26
+ # C = 'outside'
27
+ # module M
28
+ # C = 'inside'
29
+ # C # => 'inside'
30
+ # "C".constantize # => 'outside', same as ::C
31
+ # end
32
+ #
33
+ # NameError is raised when the name is not in CamelCase or the constant is
34
+ # unknown.
17
35
  def constantize(camel_cased_word)
18
36
  names = camel_cased_word.split('::')
19
37
  names.shift if names.empty? || names.first.empty?
@@ -24,6 +42,18 @@ module Modularity
24
42
  end
25
43
  constant
26
44
  end
45
+ else
46
+ def constantize(camel_cased_word) #:nodoc:
47
+ names = camel_cased_word.split('::')
48
+ names.shift if names.empty? || names.first.empty?
49
+
50
+ constant = Object
51
+ names.each do |name|
52
+ constant = constant.const_defined?(name, false) ? constant.const_get(name) : constant.const_missing(name)
53
+ end
54
+ constant
55
+ end
56
+ end
27
57
 
28
58
  end
29
59
  end
@@ -0,0 +1,3 @@
1
+ module Modularity
2
+ VERSION = '0.6.1'
3
+ end
@@ -1,56 +1,22 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'modularity/version'
5
4
 
6
5
  Gem::Specification.new do |s|
7
6
  s.name = %q{modularity}
8
- s.version = "0.6.0"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
+ s.version = Modularity::VERSION
11
8
  s.authors = ["Henning Koch"]
12
- s.date = %q{2010-02-18}
13
- s.description = %q{Traits and partial classes for Ruby}
14
9
  s.email = %q{github@makandra.de}
15
- s.extra_rdoc_files = [
16
- "README.rdoc"
17
- ]
18
- s.files = [
19
- ".gitignore",
20
- "MIT-LICENSE",
21
- "README.rdoc",
22
- "Rakefile",
23
- "VERSION",
24
- "lib/modularity.rb",
25
- "lib/modularity/as_trait.rb",
26
- "lib/modularity/does.rb",
27
- "lib/modularity/inflector.rb",
28
- "modularity.gemspec",
29
- "spec/as_trait_spec.rb",
30
- "spec/does_spec.rb",
31
- "spec/rcov.opts",
32
- "spec/spec.opts",
33
- "spec/spec_helper.rb"
34
- ]
35
10
  s.homepage = %q{http://github.com/makandra/modularity}
36
- s.rdoc_options = ["--charset=UTF-8"]
37
- s.require_paths = ["lib"]
38
- s.rubygems_version = %q{1.3.5}
39
11
  s.summary = %q{Traits and partial classes for Ruby}
40
- s.test_files = [
41
- "spec/spec_helper.rb",
42
- "spec/does_spec.rb",
43
- "spec/as_trait_spec.rb"
44
- ]
12
+ s.description = %q{Traits and partial classes for Ruby}
45
13
 
46
- if s.respond_to? :specification_version then
47
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
- s.specification_version = 3
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
49
18
 
50
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
- else
52
- end
53
- else
54
- end
55
- end
19
+ s.add_development_dependency('rake')
20
+ s.add_development_dependency('rspec', '<2')
56
21
 
22
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  module Trait
4
4
  as_trait do
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  module SomeTrait
4
4
  as_trait do
@@ -74,9 +74,9 @@ describe Modularity::AsTrait do
74
74
  does "visibility"
75
75
  end
76
76
  instance = Doer.new
77
- instance.public_methods.should include("public_method_from_trait")
78
- instance.protected_methods.should include("protected_method_from_trait")
79
- instance.private_methods.should include("private_method_from_trait")
77
+ instance.public_methods.collect(&:to_s).should include("public_method_from_trait")
78
+ instance.protected_methods.collect(&:to_s).should include("protected_method_from_trait")
79
+ instance.private_methods.collect(&:to_s).should include("private_method_from_trait")
80
80
  end
81
81
 
82
82
  it "should allow the trait to perform metaprogramming acrobatics" do
metadata CHANGED
@@ -1,36 +1,55 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: modularity
3
- version: !ruby/object:Gem::Version
4
- version: 0.6.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.1
5
+ prerelease:
5
6
  platform: ruby
6
- authors:
7
+ authors:
7
8
  - Henning Koch
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2010-02-18 00:00:00 +01:00
12
+ date: 2011-07-23 00:00:00.000000000 +02:00
13
13
  default_executable:
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: &23087620 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *23087620
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ requirement: &23087020 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - <
32
+ - !ruby/object:Gem::Version
33
+ version: '2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *23087020
16
37
  description: Traits and partial classes for Ruby
17
38
  email: github@makandra.de
18
39
  executables: []
19
-
20
40
  extensions: []
21
-
22
- extra_rdoc_files:
23
- - README.rdoc
24
- files:
41
+ extra_rdoc_files: []
42
+ files:
25
43
  - .gitignore
44
+ - Gemfile
26
45
  - MIT-LICENSE
27
46
  - README.rdoc
28
47
  - Rakefile
29
- - VERSION
30
48
  - lib/modularity.rb
31
49
  - lib/modularity/as_trait.rb
32
50
  - lib/modularity/does.rb
33
51
  - lib/modularity/inflector.rb
52
+ - lib/modularity/version.rb
34
53
  - modularity.gemspec
35
54
  - spec/as_trait_spec.rb
36
55
  - spec/does_spec.rb
@@ -40,32 +59,31 @@ files:
40
59
  has_rdoc: true
41
60
  homepage: http://github.com/makandra/modularity
42
61
  licenses: []
43
-
44
62
  post_install_message:
45
- rdoc_options:
46
- - --charset=UTF-8
47
- require_paths:
63
+ rdoc_options: []
64
+ require_paths:
48
65
  - lib
49
- required_ruby_version: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: "0"
54
- version:
55
- required_rubygems_version: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- version: "0"
60
- version:
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
61
78
  requirements: []
62
-
63
79
  rubyforge_project:
64
- rubygems_version: 1.3.5
80
+ rubygems_version: 1.6.2
65
81
  signing_key:
66
82
  specification_version: 3
67
83
  summary: Traits and partial classes for Ruby
68
- test_files:
69
- - spec/spec_helper.rb
70
- - spec/does_spec.rb
84
+ test_files:
71
85
  - spec/as_trait_spec.rb
86
+ - spec/does_spec.rb
87
+ - spec/rcov.opts
88
+ - spec/spec.opts
89
+ - spec/spec_helper.rb
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.6.0