common_name 0.1.4

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