modularity 0.6.0 → 0.6.1

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/.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