common_name 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Seamus Abshere
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,171 @@
1
+ =common_name
2
+
3
+ Stop needing to use humanize/downcase/underscore/pluralize/to_sym/etc to derive a common name.
4
+
5
+ ==Why this is useful
6
+
7
+ In our app, we have lots of classes that share something (a name) in common:
8
+
9
+ * <tt>class Automobile < Emitter</tt>
10
+ * <tt>class AutomobilesController < EmittersController</tt>
11
+ * <tt>class AutomobilesComponent < Component</tt>
12
+ * <tt>class AutomobileVersion < EmitterVersion</tt>
13
+ * <tt>Boat</tt> et al., <tt>Flight</tt> et al., etc.
14
+
15
+ Of course, there are a million ways to derive the word "automobile" from any of these class names. We could fill up our app with humanize/downcase/underscore/pluralize, but we think that's sloppy.
16
+
17
+ So we use <tt>common_name</tt>:
18
+
19
+ >> Automobile.common_name
20
+ => "automobile"
21
+ >> Automobile.new.common_name
22
+ => "automobile"
23
+ >> AutomobilesController.common_name
24
+ => "automobile"
25
+ >> AutomobilesController.new.common_name
26
+ => "automobile"
27
+ >> AutomobilesComponent.common_name
28
+ => "automobile"
29
+ >> AutomobilesComponent.new.common_name
30
+ => "automobile"
31
+ >> AutomobileVersion.common_name
32
+ => "automobile"
33
+ >> AutomobileVersion.new.common_name
34
+ => "automobile"
35
+
36
+ And when metaprogramming:
37
+
38
+ module EmitterVersionExtensions
39
+ def self.included(klass)
40
+ klass.class_eval do
41
+ set_table_name "#{common_name}_versions" # set_table_name "automobile_versions"
42
+ belongs_to common_symbol # belongs_to :automobile
43
+ has_one :profile, :through => common_symbol # has_one :profile, :through => :automobile
44
+ end
45
+ end
46
+ end
47
+
48
+ We also end up using this constantly in views.
49
+
50
+ ==Quick reference
51
+
52
+ Here are all the methods it gives you:
53
+
54
+ common_name => "bus_company"
55
+ common_symbol => :bus_company
56
+ common_instance => "@bus_company"
57
+ common_title => "Bus company"
58
+ common_human => "bus company"
59
+ common_camel => "BusCompany"
60
+
61
+ common_plural => "bus_companies"
62
+ common_plural_symbol => :bus_companies
63
+ common_plural_instance => "@bus_companies"
64
+ common_plural_title => "Bus companies"
65
+ common_plural_human => "bus companies"
66
+ common_plural_camel => "BusCompanies"
67
+
68
+ common_model => BusCompany [the class]
69
+
70
+ ==Quick start
71
+
72
+ Put this in <tt>config/environment.rb</tt>
73
+
74
+ config.gem 'common_name'
75
+
76
+ Put this in <tt>config/initializers/common_name.rb</tt>... (it will let you say <tt>BusCompany.common_name</tt> and get the string "bus_company")
77
+
78
+ ActiveRecord::Base.class_eval do
79
+ class << self; def _common_name; name.underscore; end; end
80
+ include CommonName
81
+ end
82
+
83
+ Put this in <tt>app/controllers/application_controller.rb</tt>... (in the CareersController, it will let you say <tt>common_model</tt> and get the class Career)
84
+
85
+ class ApplicationController < ActionController::Base
86
+ class << self; def _common_name; controller_name.singularize; end; end
87
+ include CommonName
88
+ end
89
+
90
+ Put this in <tt>app/helpers/application_helper.rb</tt>... (in careers/show, it will let you say <tt><%= common_plural_title %></tt> and see "Careers")
91
+
92
+ module ApplicationHelper
93
+ CommonName::METHODS.each do |m|
94
+ eval %{ def common_#{m}; controller.common_#{m}; end }
95
+ end
96
+ end
97
+
98
+ ==What it's not
99
+
100
+ It's <em>not</em> a replacement for <tt>humanize</tt>, <tt>pluralize</tt>, etc.
101
+
102
+ >> "bus_company".common_title
103
+ NoMethodError: undefined method 'common_title' for "bus company":String
104
+
105
+ The point is to cover common names of classes and their instances.
106
+
107
+ ==Advanced usage
108
+
109
+ The <tt>_common_name</tt> method should provide an <em>underscored</em> form that will be used to derive other common forms like <tt>common_human</tt> and <tt>common_plural_symbol</tt>.
110
+
111
+ Note that calling <tt>common_<i>X</i></tt> on a class and on its instances will return the same value.
112
+
113
+ I also use it on non-ActiveRecord classes:
114
+
115
+ class FooBar
116
+ class << self; def _common_name; name.underscore; end; end
117
+ include CommonName
118
+ end
119
+
120
+ >> FooBar.common_name
121
+ => "foo_bar"
122
+ >> f.common_name # f = FooBar.new
123
+ => "foo_bar"
124
+
125
+ If you define <tt>_common_plural</tt>, it will be the basis for the plural forms:
126
+
127
+ class Government
128
+ class << self
129
+ def _common_name
130
+ 'government'
131
+ end
132
+ def _common_plural
133
+ 'government'
134
+ end
135
+ end
136
+ include CommonName
137
+ end
138
+
139
+ That way you can enforce uncountability
140
+
141
+ Government.common_name == Government.common_plural
142
+
143
+ without setting a general rule in the Inflector that the word "government" is uncountable.
144
+
145
+ ==Rationale
146
+
147
+ I don't like chains of humanize/downcase/underscore/pluralize/to_sym, for example:
148
+
149
+ >> BusCompany.name.underscore.humanize.downcase.pluralize
150
+ => "bus companies"
151
+
152
+ So I replaced them with easy-to-remember methods like:
153
+
154
+ >> BusCompany.common_plural_human
155
+ => "bus companies"
156
+
157
+ I also didn't like worrying about .name versus .class.name:
158
+
159
+ >> @bus_company.class.name # @bus_company = BusCompany.new
160
+ => "BusCompany"
161
+ >> @bus_company.name
162
+ => ""
163
+
164
+ So, the <tt>common_name</tt> of a class (<tt>BusCompany</tt>) is always equivalent to the <tt>common_name</tt> of its instances (<tt>@bus_company</tt>):
165
+
166
+ >> BusCompany.common_plural_human == @bus_company.common_plural_human
167
+ => true
168
+
169
+ ==Copyright
170
+
171
+ Copyright (c) 2009 Seamus Abshere. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,61 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "common_name"
8
+ gem.summary = %Q{DRY up humanize/downcase/underscore/pluralize/to_sym/etc for names that we use all the time.}
9
+ gem.description = %Q{Provides methods like User.common_name (#=> "user") and User.common_plural_symbol (#=> :users) so that you don't have to chain humanize/downcase/etc. etc.'}
10
+ gem.email = "seamus@abshere.net"
11
+ gem.homepage = "http://github.com/seamusabshere/common_name"
12
+ gem.authors = ["Seamus Abshere"]
13
+ gem.add_dependency 'activesupport'
14
+ gem.rubyforge_project = "commonname"
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ Jeweler::RubyforgeTasks.new do |rubyforge|
18
+ rubyforge.doc_task = "rdoc"
19
+ end
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/*_test.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/*_test.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+
45
+
46
+
47
+ task :default => :test
48
+
49
+ require 'rake/rdoctask'
50
+ Rake::RDocTask.new do |rdoc|
51
+ if File.exist?('VERSION')
52
+ version = File.read('VERSION')
53
+ else
54
+ version = ""
55
+ end
56
+
57
+ rdoc.rdoc_dir = 'rdoc'
58
+ rdoc.title = "common_name #{version}"
59
+ rdoc.rdoc_files.include('README*')
60
+ rdoc.rdoc_files.include('lib/**/*.rb')
61
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.4
@@ -0,0 +1,55 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{common_name}
8
+ s.version = "0.1.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Seamus Abshere"]
12
+ s.date = %q{2009-10-30}
13
+ s.description = %q{Provides methods like User.common_name (#=> "user") and User.common_plural_symbol (#=> :users) so that you don't have to chain humanize/downcase/etc. etc.'}
14
+ s.email = %q{seamus@abshere.net}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "common_name.gemspec",
27
+ "lib/common_name.rb",
28
+ "test/common_name_test.rb",
29
+ "test/test_helper.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/seamusabshere/common_name}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubyforge_project = %q{commonname}
35
+ s.rubygems_version = %q{1.3.5}
36
+ s.summary = %q{DRY up humanize/downcase/underscore/pluralize/to_sym/etc for names that we use all the time.}
37
+ s.test_files = [
38
+ "test/common_name_test.rb",
39
+ "test/test_helper.rb"
40
+ ]
41
+
42
+ if s.respond_to? :specification_version then
43
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
48
+ else
49
+ s.add_dependency(%q<activesupport>, [">= 0"])
50
+ end
51
+ else
52
+ s.add_dependency(%q<activesupport>, [">= 0"])
53
+ end
54
+ end
55
+
@@ -0,0 +1,86 @@
1
+ # This library comes out of my frustration with seeing lines like
2
+ #
3
+ # BusCompany.name.underscore.humanize.downcase.pluralize #=> "bus companies"
4
+ #
5
+ # all over my application.
6
+ #
7
+ # See <tt>README</tt> for more information.
8
+ #
9
+ # Copyright (c) 2009 Seamus Abshere. See LICENSE for details.
10
+
11
+ require 'rubygems'
12
+ require 'activesupport'
13
+
14
+ module CommonName
15
+ def self.included(klass)
16
+ klass.extend ClassMethods
17
+ end
18
+
19
+ METHODS = %w{
20
+ name symbol instance title human camel
21
+ plural plural_symbol plural_instance plural_title plural_human plural_camel
22
+ model
23
+ }
24
+
25
+ # delegate instance methods to class methods
26
+ METHODS.each do |m|
27
+ eval %{ def common_#{m}; self.class.common_#{m}; end }
28
+ end
29
+
30
+ module ClassMethods
31
+ # "bus_company"
32
+ #
33
+ # Identical to <tt>_common_name</tt>, which you have to provide.
34
+ def common_name; _COMMON_NAME ||= _common_name; end
35
+
36
+ # :bus_company
37
+ def common_symbol; _COMMON_SYMBOL ||= common_name.to_sym; end
38
+
39
+ # "@bus_company"
40
+ #
41
+ # For use with <tt>instance_variable_get</tt>, etc.
42
+ def common_instance; _COMMON_INSTANCE ||= '@' << common_name; end
43
+
44
+ # "Bus company"
45
+ #
46
+ # Microsoft titlecase.
47
+ def common_title; _COMMON_TITLE ||= common_name.humanize; end
48
+
49
+ # "bus company"
50
+ #
51
+ # Unlike <tt>humanize</tt>, this is lowercase.
52
+ def common_human; _COMMON_HUMAN ||= common_title.downcase; end
53
+
54
+ # "BusCompany"
55
+ def common_camel; _COMMON_CAMEL ||= common_name.camelcase; end
56
+
57
+ # BusCompany
58
+ #
59
+ # Already constantized.
60
+ def common_model; _COMMON_MODEL ||= common_camel.constantize; end
61
+
62
+ # "bus_companies"
63
+ #
64
+ # Derived from _common_name, unless you provide _common_plural.
65
+ def common_plural; _COMMON_PLURAL ||= (respond_to?(:_common_plural) ? _common_plural : common_name.pluralize); end
66
+
67
+ # :bus_companies
68
+ def common_plural_symbol; _COMMON_PLURAL_SYMBOL ||= common_plural.to_sym; end
69
+
70
+ # "@bus_companies"
71
+ def common_plural_instance; _COMMON_PLURAL_INSTANCE ||= '@' << common_plural; end
72
+
73
+ # "Bus companies"
74
+ #
75
+ # See +common_title+ for notes on capitalization.
76
+ def common_plural_title; _COMMON_PLURAL_TITLE ||= common_plural.humanize; end
77
+
78
+ # "bus companies"
79
+ #
80
+ # See +common_human+ for notes on capitalization.
81
+ def common_plural_human; _COMMON_PLURAL_HUMAN ||= common_plural_title.downcase; end
82
+
83
+ # "BusCompanies"
84
+ def common_plural_camel; _COMMON_PLURAL_CAMEL ||= common_plural.camelcase; end
85
+ end
86
+ end
@@ -0,0 +1,88 @@
1
+ require 'test_helper'
2
+
3
+ # a pretty normal class
4
+ class BusCompany
5
+ def self._common_name
6
+ name.underscore
7
+ end
8
+ include CommonName
9
+ end
10
+
11
+ # a class where you always want to chop off the _component part and singularize
12
+ class Component
13
+ def self._common_name
14
+ name.underscore.gsub('_component', '').singularize
15
+ end
16
+ include CommonName
17
+ end
18
+ class AutomobilesComponent < Component; end
19
+ class GovernmentComponent < Component
20
+ def self._common_plural
21
+ 'government'
22
+ end
23
+ end
24
+
25
+ class CommonNameTest < Test::Unit::TestCase
26
+ should "have required API method" do
27
+ assert BusCompany.respond_to?(:_common_name)
28
+ assert Component.respond_to?(:_common_name)
29
+ end
30
+
31
+ should "have optional API method" do
32
+ assert !Component.respond_to?(:_common_plural)
33
+ assert GovernmentComponent.respond_to?(:_common_plural)
34
+ end
35
+
36
+ should "have underscored common name" do
37
+ assert !BusCompany._common_name.include?(' ')
38
+ assert !Component._common_name.include?(' ')
39
+ end
40
+
41
+ {
42
+ :common_name => "bus_company",
43
+ :common_symbol => :bus_company,
44
+ :common_instance => "@bus_company",
45
+ :common_title => "Bus company",
46
+ :common_human => "bus company",
47
+ :common_camel => "BusCompany",
48
+ :common_plural => "bus_companies",
49
+ :common_plural_symbol => :bus_companies,
50
+ :common_plural_instance => "@bus_companies",
51
+ :common_plural_title => "Bus companies",
52
+ :common_plural_human => "bus companies",
53
+ :common_plural_camel => "BusCompanies",
54
+ :common_model => BusCompany
55
+ }.each do |method, result|
56
+ should "have #{method} at the class level" do
57
+ assert_equal result, BusCompany.send(method)
58
+ end
59
+
60
+ should "have #{method} at the instance level" do
61
+ assert_equal result, BusCompany.send(method)
62
+ end
63
+ end
64
+
65
+ should "have common name at the class level" do
66
+ assert_equal "component", Component.common_name
67
+ assert_equal "automobile", AutomobilesComponent.common_name
68
+ assert_equal "government", GovernmentComponent.common_name
69
+ end
70
+
71
+ should "have common name at the instance level" do
72
+ assert_equal "component", Component.new.common_name
73
+ assert_equal "automobile", AutomobilesComponent.new.common_name
74
+ assert_equal "government", GovernmentComponent.new.common_name
75
+ end
76
+
77
+ should "have common plural at the class level" do
78
+ assert_equal "components", Component.common_plural
79
+ assert_equal "automobiles", AutomobilesComponent.common_plural
80
+ assert_equal "government", GovernmentComponent.common_plural # uncountable
81
+ end
82
+
83
+ should "have common plural at the instance level" do
84
+ assert_equal "components", Component.new.common_plural
85
+ assert_equal "automobiles", AutomobilesComponent.new.common_plural
86
+ assert_equal "government", GovernmentComponent.new.common_plural # uncountable
87
+ end
88
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'common_name'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: common_name
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Seamus Abshere
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-30 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Provides methods like User.common_name (#=> "user") and User.common_plural_symbol (#=> :users) so that you don't have to chain humanize/downcase/etc. etc.'
26
+ email: seamus@abshere.net
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - common_name.gemspec
42
+ - lib/common_name.rb
43
+ - test/common_name_test.rb
44
+ - test/test_helper.rb
45
+ has_rdoc: true
46
+ homepage: http://github.com/seamusabshere/common_name
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project: commonname
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: DRY up humanize/downcase/underscore/pluralize/to_sym/etc for names that we use all the time.
73
+ test_files:
74
+ - test/common_name_test.rb
75
+ - test/test_helper.rb