activesupport-inflector 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +22 -0
- data/Gemfile +2 -0
- data/README.md +4 -0
- data/Rakefile +14 -0
- data/activesupport-inflector.gemspec +18 -0
- data/lib/active_support/core_ext/array/extract_options.rb +29 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +64 -0
- data/lib/active_support/core_ext/string/access.rb +99 -0
- data/lib/active_support/core_ext/string/behavior.rb +6 -0
- data/lib/active_support/core_ext/string/inflections.rb +202 -0
- data/lib/active_support/core_ext/string/multibyte.rb +72 -0
- data/lib/active_support/i18n.rb +9 -0
- data/lib/active_support/inflections.rb +63 -0
- data/lib/active_support/inflector.rb +7 -0
- data/lib/active_support/inflector/inflections.rb +174 -0
- data/lib/active_support/inflector/methods.rb +321 -0
- data/lib/active_support/inflector/transliterate.rb +98 -0
- data/lib/active_support/lazy_load_hooks.rb +46 -0
- data/lib/active_support/multibyte.rb +44 -0
- data/lib/active_support/multibyte/chars.rb +476 -0
- data/lib/active_support/multibyte/exceptions.rb +8 -0
- data/lib/active_support/multibyte/unicode.rb +393 -0
- data/lib/active_support/multibyte/utils.rb +60 -0
- metadata +66 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YTZjNzQzNmViZTNiMDY4Yjc1NDgzMjIxNjgwODdlMjFjZGJmOGRmNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Y2IzODljMTRjMzkxYWNlODE3MzgxZWQxMTBlZjZlZGI0ZGNiYWIzZQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YzY0ZWYyZDNhZDFkYjAxYzBmMTU2ZmJjY2ZmOTZiOGE1OGI2Y2FkYzFmNjkw
|
10
|
+
Yjc2ODM4ZmY1ZTUyMDA5M2FhZjA1ZmVlOTUxODUzOTdiOGVlOGJmZjU0MzBm
|
11
|
+
M2M4M2E2MmY4NWI3ZmE5MzIxYjAxZGNhNGY2YjFkYzVjNDdlYjU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDYyZTQ0OTk0ZTBjZjc4MGRkNmRlYmY4MDAxNTYyZjI4M2Y4NWRlNmVlMWY0
|
14
|
+
YzgyMTk5NzIwMzkxNjZlODc3YmRmZTNmYjhjMWIxMjExYmU2ZDdiZjZhYzg3
|
15
|
+
ZWU1M2Y1YzU3YWY5Yjk3M2UxMjdjNDVkNGRiYWJjYTA3ZGE1NWM=
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
coverage
|
6
|
+
InstalledFiles
|
7
|
+
lib/bundler/man
|
8
|
+
pkg
|
9
|
+
rdoc
|
10
|
+
spec/reports
|
11
|
+
test/tmp
|
12
|
+
test/version_tmp
|
13
|
+
tmp
|
14
|
+
|
15
|
+
# YARD artifacts
|
16
|
+
.yardoc
|
17
|
+
_yardoc
|
18
|
+
doc/
|
19
|
+
.DS_Store
|
20
|
+
.idea/
|
21
|
+
.idea/*
|
22
|
+
Gemfile.lock
|
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
# Default Rake task is compile
|
5
|
+
#task :default => :compile
|
6
|
+
|
7
|
+
########################################################################
|
8
|
+
|
9
|
+
Rake::TestTask.new do |t|
|
10
|
+
t.libs.push "lib"
|
11
|
+
t.libs.push "test"
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = false
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'activesupport-inflector'
|
7
|
+
gem.version = '0.0.1'
|
8
|
+
gem.date = '2012-10-19'
|
9
|
+
gem.summary = %q{Only the Inflector part of ActiveRecord.}
|
10
|
+
gem.authors = ['Caleb Clark']
|
11
|
+
gem.email = ['cclark@fanforce.com']
|
12
|
+
gem.homepage = 'http://github.com/calebclark/activesupport-inflector'
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($/)
|
15
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
|
+
gem.require_paths = ['lib']
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Hash
|
2
|
+
# By default, only instances of Hash itself are extractable.
|
3
|
+
# Subclasses of Hash may implement this method and return
|
4
|
+
# true to declare themselves as extractable. If a Hash
|
5
|
+
# is extractable, Array#extract_options! pops it from
|
6
|
+
# the Array when it is the last element of the Array.
|
7
|
+
def extractable_options?
|
8
|
+
instance_of?(Hash)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Array
|
13
|
+
# Extracts options from a set of arguments. Removes and returns the last
|
14
|
+
# element in the array if it's a hash, otherwise returns a blank hash.
|
15
|
+
#
|
16
|
+
# def options(*args)
|
17
|
+
# args.extract_options!
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# options(1, 2) # => {}
|
21
|
+
# options(1, 2, :a => :b) # => {:a=>:b}
|
22
|
+
def extract_options!
|
23
|
+
if last.is_a?(Hash) && last.extractable_options?
|
24
|
+
pop
|
25
|
+
else
|
26
|
+
{}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'active_support/core_ext/array/extract_options'
|
2
|
+
|
3
|
+
class Module
|
4
|
+
def mattr_reader(*syms)
|
5
|
+
options = syms.extract_options!
|
6
|
+
syms.each do |sym|
|
7
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
8
|
+
@@#{sym} = nil unless defined? @@#{sym}
|
9
|
+
|
10
|
+
def self.#{sym}
|
11
|
+
@@#{sym}
|
12
|
+
end
|
13
|
+
EOS
|
14
|
+
|
15
|
+
unless options[:instance_reader] == false || options[:instance_accessor] == false
|
16
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
17
|
+
def #{sym}
|
18
|
+
@@#{sym}
|
19
|
+
end
|
20
|
+
EOS
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def mattr_writer(*syms)
|
26
|
+
options = syms.extract_options!
|
27
|
+
syms.each do |sym|
|
28
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
29
|
+
def self.#{sym}=(obj)
|
30
|
+
@@#{sym} = obj
|
31
|
+
end
|
32
|
+
EOS
|
33
|
+
|
34
|
+
unless options[:instance_writer] == false || options[:instance_accessor] == false
|
35
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
36
|
+
def #{sym}=(obj)
|
37
|
+
@@#{sym} = obj
|
38
|
+
end
|
39
|
+
EOS
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Extends the module object with module and instance accessors for class attributes,
|
45
|
+
# just like the native attr* accessors for instance attributes.
|
46
|
+
#
|
47
|
+
# module AppConfiguration
|
48
|
+
# mattr_accessor :google_api_key
|
49
|
+
# self.google_api_key = "123456789"
|
50
|
+
#
|
51
|
+
# mattr_accessor :paypal_url
|
52
|
+
# self.paypal_url = "www.sandbox.paypal.com"
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# AppConfiguration.google_api_key = "overriding the api key!"
|
56
|
+
#
|
57
|
+
# To opt out of the instance writer method, pass :instance_writer => false.
|
58
|
+
# To opt out of the instance reader method, pass :instance_reader => false.
|
59
|
+
# To opt out of both instance methods, pass :instance_accessor => false.
|
60
|
+
def mattr_accessor(*syms)
|
61
|
+
mattr_reader(*syms)
|
62
|
+
mattr_writer(*syms)
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require "active_support/multibyte"
|
2
|
+
|
3
|
+
class String
|
4
|
+
unless '1.9'.respond_to?(:force_encoding)
|
5
|
+
# Returns the character at the +position+ treating the string as an array (where 0 is the first character).
|
6
|
+
#
|
7
|
+
# Examples:
|
8
|
+
# "hello".at(0) # => "h"
|
9
|
+
# "hello".at(4) # => "o"
|
10
|
+
# "hello".at(10) # => ERROR if < 1.9, nil in 1.9
|
11
|
+
def at(position)
|
12
|
+
mb_chars[position, 1].to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the remaining of the string from the +position+ treating the string as an array (where 0 is the first character).
|
16
|
+
#
|
17
|
+
# Examples:
|
18
|
+
# "hello".from(0) # => "hello"
|
19
|
+
# "hello".from(2) # => "llo"
|
20
|
+
# "hello".from(10) # => "" if < 1.9, nil in 1.9
|
21
|
+
def from(position)
|
22
|
+
mb_chars[position..-1].to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the beginning of the string up to the +position+ treating the string as an array (where 0 is the first character).
|
26
|
+
#
|
27
|
+
# Examples:
|
28
|
+
# "hello".to(0) # => "h"
|
29
|
+
# "hello".to(2) # => "hel"
|
30
|
+
# "hello".to(10) # => "hello"
|
31
|
+
def to(position)
|
32
|
+
mb_chars[0..position].to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the first character of the string or the first +limit+ characters.
|
36
|
+
#
|
37
|
+
# Examples:
|
38
|
+
# "hello".first # => "h"
|
39
|
+
# "hello".first(2) # => "he"
|
40
|
+
# "hello".first(10) # => "hello"
|
41
|
+
def first(limit = 1)
|
42
|
+
if limit == 0
|
43
|
+
''
|
44
|
+
elsif limit >= size
|
45
|
+
self
|
46
|
+
else
|
47
|
+
mb_chars[0...limit].to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the last character of the string or the last +limit+ characters.
|
52
|
+
#
|
53
|
+
# Examples:
|
54
|
+
# "hello".last # => "o"
|
55
|
+
# "hello".last(2) # => "lo"
|
56
|
+
# "hello".last(10) # => "hello"
|
57
|
+
def last(limit = 1)
|
58
|
+
if limit == 0
|
59
|
+
''
|
60
|
+
elsif limit >= size
|
61
|
+
self
|
62
|
+
else
|
63
|
+
mb_chars[(-limit)..-1].to_s
|
64
|
+
end
|
65
|
+
end
|
66
|
+
else
|
67
|
+
def at(position)
|
68
|
+
self[position]
|
69
|
+
end
|
70
|
+
|
71
|
+
def from(position)
|
72
|
+
self[position..-1]
|
73
|
+
end
|
74
|
+
|
75
|
+
def to(position)
|
76
|
+
self[0..position]
|
77
|
+
end
|
78
|
+
|
79
|
+
def first(limit = 1)
|
80
|
+
if limit == 0
|
81
|
+
''
|
82
|
+
elsif limit >= size
|
83
|
+
self
|
84
|
+
else
|
85
|
+
to(limit - 1)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def last(limit = 1)
|
90
|
+
if limit == 0
|
91
|
+
''
|
92
|
+
elsif limit >= size
|
93
|
+
self
|
94
|
+
else
|
95
|
+
from(-limit)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'active_support/inflector/methods'
|
2
|
+
require 'active_support/inflector/transliterate'
|
3
|
+
|
4
|
+
# String inflections define new methods on the String class to transform names for different purposes.
|
5
|
+
# For instance, you can figure out the name of a table from the name of a class.
|
6
|
+
#
|
7
|
+
# "ScaleScore".tableize # => "scale_scores"
|
8
|
+
#
|
9
|
+
class String
|
10
|
+
# Returns the plural form of the word in the string.
|
11
|
+
#
|
12
|
+
# If the optional parameter +count+ is specified,
|
13
|
+
# the singular form will be returned if <tt>count == 1</tt>.
|
14
|
+
# For any other value of +count+ the plural will be returned.
|
15
|
+
#
|
16
|
+
# ==== Examples
|
17
|
+
# "post".pluralize # => "posts"
|
18
|
+
# "octopus".pluralize # => "octopi"
|
19
|
+
# "sheep".pluralize # => "sheep"
|
20
|
+
# "words".pluralize # => "words"
|
21
|
+
# "the blue mailman".pluralize # => "the blue mailmen"
|
22
|
+
# "CamelOctopus".pluralize # => "CamelOctopi"
|
23
|
+
# "apple".pluralize(1) # => "apple"
|
24
|
+
# "apple".pluralize(2) # => "apples"
|
25
|
+
def pluralize(count = nil)
|
26
|
+
if count == 1
|
27
|
+
self
|
28
|
+
else
|
29
|
+
ActiveSupport::Inflector.pluralize(self)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# The reverse of +pluralize+, returns the singular form of a word in a string.
|
34
|
+
#
|
35
|
+
# "posts".singularize # => "post"
|
36
|
+
# "octopi".singularize # => "octopus"
|
37
|
+
# "sheep".singularize # => "sheep"
|
38
|
+
# "word".singularize # => "word"
|
39
|
+
# "the blue mailmen".singularize # => "the blue mailman"
|
40
|
+
# "CamelOctopi".singularize # => "CamelOctopus"
|
41
|
+
def singularize
|
42
|
+
ActiveSupport::Inflector.singularize(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
# +constantize+ tries to find a declared constant with the name specified
|
46
|
+
# in the string. It raises a NameError when the name is not in CamelCase
|
47
|
+
# or is not initialized. See ActiveSupport::Inflector.constantize
|
48
|
+
#
|
49
|
+
# Examples
|
50
|
+
# "Module".constantize # => Module
|
51
|
+
# "Class".constantize # => Class
|
52
|
+
# "blargle".constantize # => NameError: wrong constant name blargle
|
53
|
+
def constantize
|
54
|
+
ActiveSupport::Inflector.constantize(self)
|
55
|
+
end
|
56
|
+
|
57
|
+
# +safe_constantize+ tries to find a declared constant with the name specified
|
58
|
+
# in the string. It returns nil when the name is not in CamelCase
|
59
|
+
# or is not initialized. See ActiveSupport::Inflector.safe_constantize
|
60
|
+
#
|
61
|
+
# Examples
|
62
|
+
# "Module".safe_constantize # => Module
|
63
|
+
# "Class".safe_constantize # => Class
|
64
|
+
# "blargle".safe_constantize # => nil
|
65
|
+
def safe_constantize
|
66
|
+
ActiveSupport::Inflector.safe_constantize(self)
|
67
|
+
end
|
68
|
+
|
69
|
+
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
|
70
|
+
# is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
|
71
|
+
#
|
72
|
+
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
|
73
|
+
#
|
74
|
+
# "active_record".camelize # => "ActiveRecord"
|
75
|
+
# "active_record".camelize(:lower) # => "activeRecord"
|
76
|
+
# "active_record/errors".camelize # => "ActiveRecord::Errors"
|
77
|
+
# "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
|
78
|
+
def camelize(first_letter = :upper)
|
79
|
+
case first_letter
|
80
|
+
when :upper then ActiveSupport::Inflector.camelize(self, true)
|
81
|
+
when :lower then ActiveSupport::Inflector.camelize(self, false)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
alias_method :camelcase, :camelize
|
85
|
+
|
86
|
+
# Capitalizes all the words and replaces some characters in the string to create
|
87
|
+
# a nicer looking title. +titleize+ is meant for creating pretty output. It is not
|
88
|
+
# used in the Rails internals.
|
89
|
+
#
|
90
|
+
# +titleize+ is also aliased as +titlecase+.
|
91
|
+
#
|
92
|
+
# "man from the boondocks".titleize # => "Man From The Boondocks"
|
93
|
+
# "x-men: the last stand".titleize # => "X Men: The Last Stand"
|
94
|
+
def titleize
|
95
|
+
ActiveSupport::Inflector.titleize(self)
|
96
|
+
end
|
97
|
+
alias_method :titlecase, :titleize
|
98
|
+
|
99
|
+
# The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
|
100
|
+
#
|
101
|
+
# +underscore+ will also change '::' to '/' to convert namespaces to paths.
|
102
|
+
#
|
103
|
+
# "ActiveModel".underscore # => "active_model"
|
104
|
+
# "ActiveModel::Errors".underscore # => "active_model/errors"
|
105
|
+
def underscore
|
106
|
+
ActiveSupport::Inflector.underscore(self)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Replaces underscores with dashes in the string.
|
110
|
+
#
|
111
|
+
# "puni_puni" # => "puni-puni"
|
112
|
+
def dasherize
|
113
|
+
ActiveSupport::Inflector.dasherize(self)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Removes the module part from the constant expression in the string.
|
117
|
+
#
|
118
|
+
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
|
119
|
+
# "Inflections".demodulize # => "Inflections"
|
120
|
+
#
|
121
|
+
# See also +deconstantize+.
|
122
|
+
def demodulize
|
123
|
+
ActiveSupport::Inflector.demodulize(self)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Removes the rightmost segment from the constant expression in the string.
|
127
|
+
#
|
128
|
+
# "Net::HTTP".deconstantize # => "Net"
|
129
|
+
# "::Net::HTTP".deconstantize # => "::Net"
|
130
|
+
# "String".deconstantize # => ""
|
131
|
+
# "::String".deconstantize # => ""
|
132
|
+
# "".deconstantize # => ""
|
133
|
+
#
|
134
|
+
# See also +demodulize+.
|
135
|
+
def deconstantize
|
136
|
+
ActiveSupport::Inflector.deconstantize(self)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
|
140
|
+
#
|
141
|
+
# ==== Examples
|
142
|
+
#
|
143
|
+
# class Person
|
144
|
+
# def to_param
|
145
|
+
# "#{id}-#{name.parameterize}"
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# @person = Person.find(1)
|
150
|
+
# # => #<Person id: 1, name: "Donald E. Knuth">
|
151
|
+
#
|
152
|
+
# <%= link_to(@person.name, person_path %>
|
153
|
+
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
|
154
|
+
def parameterize(sep = '-')
|
155
|
+
ActiveSupport::Inflector.parameterize(self, sep)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Creates the name of a table like Rails does for models to table names. This method
|
159
|
+
# uses the +pluralize+ method on the last word in the string.
|
160
|
+
#
|
161
|
+
# "RawScaledScorer".tableize # => "raw_scaled_scorers"
|
162
|
+
# "egg_and_ham".tableize # => "egg_and_hams"
|
163
|
+
# "fancyCategory".tableize # => "fancy_categories"
|
164
|
+
def tableize
|
165
|
+
ActiveSupport::Inflector.tableize(self)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Create a class name from a plural table name like Rails does for table names to models.
|
169
|
+
# Note that this returns a string and not a class. (To convert to an actual class
|
170
|
+
# follow +classify+ with +constantize+.)
|
171
|
+
#
|
172
|
+
# "egg_and_hams".classify # => "EggAndHam"
|
173
|
+
# "posts".classify # => "Post"
|
174
|
+
#
|
175
|
+
# Singular names are not handled correctly.
|
176
|
+
#
|
177
|
+
# "business".classify # => "Busines"
|
178
|
+
def classify
|
179
|
+
ActiveSupport::Inflector.classify(self)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Capitalizes the first word, turns underscores into spaces, and strips '_id'.
|
183
|
+
# Like +titleize+, this is meant for creating pretty output.
|
184
|
+
#
|
185
|
+
# "employee_salary" # => "Employee salary"
|
186
|
+
# "author_id" # => "Author"
|
187
|
+
def humanize
|
188
|
+
ActiveSupport::Inflector.humanize(self)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Creates a foreign key name from a class name.
|
192
|
+
# +separate_class_name_and_id_with_underscore+ sets whether
|
193
|
+
# the method should put '_' between the name and 'id'.
|
194
|
+
#
|
195
|
+
# Examples
|
196
|
+
# "Message".foreign_key # => "message_id"
|
197
|
+
# "Message".foreign_key(false) # => "messageid"
|
198
|
+
# "Admin::Post".foreign_key # => "post_id"
|
199
|
+
def foreign_key(separate_class_name_and_id_with_underscore = true)
|
200
|
+
ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
|
201
|
+
end
|
202
|
+
end
|