activeobject 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGE +10 -0
- data/Interface_desc +21 -0
- data/MIT-LICENSE +20 -0
- data/README +72 -0
- data/Rakefile.rb +9 -0
- data/active-object.gemspec +50 -0
- data/examples/account.rb +69 -0
- data/examples/data.tch +0 -0
- data/examples/light_cloud.yml +18 -0
- data/examples/test.rb +3 -0
- data/examples/user.rb +112 -0
- data/init.rb +4 -0
- data/lib/active-object.rb +23 -0
- data/lib/active_object/adapters/light_cloud.rb +40 -0
- data/lib/active_object/adapters/tokyo_cabinet.rb +48 -0
- data/lib/active_object/adapters/tokyo_tyrant.rb +14 -0
- data/lib/active_object/associations.rb +200 -0
- data/lib/active_object/base.rb +415 -0
- data/lib/active_object/callbacks.rb +180 -0
- data/lib/active_object/observer.rb +180 -0
- data/lib/active_object/serialization.rb +99 -0
- data/lib/active_object/serializers/json_serializer.rb +75 -0
- data/lib/active_object/serializers/xml_serializer.rb +325 -0
- data/lib/active_object/validations.rb +687 -0
- data/lib/active_support/callbacks.rb +303 -0
- data/lib/active_support/core_ext/array/access.rb +53 -0
- data/lib/active_support/core_ext/array/conversions.rb +183 -0
- data/lib/active_support/core_ext/array/extract_options.rb +20 -0
- data/lib/active_support/core_ext/array/grouping.rb +106 -0
- data/lib/active_support/core_ext/array/random_access.rb +12 -0
- data/lib/active_support/core_ext/array.rb +13 -0
- data/lib/active_support/core_ext/blank.rb +58 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +54 -0
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +140 -0
- data/lib/active_support/core_ext/class/removal.rb +50 -0
- data/lib/active_support/core_ext/class.rb +3 -0
- data/lib/active_support/core_ext/duplicable.rb +43 -0
- data/lib/active_support/core_ext/enumerable.rb +72 -0
- data/lib/active_support/core_ext/hash/conversions.rb +259 -0
- data/lib/active_support/core_ext/hash/keys.rb +52 -0
- data/lib/active_support/core_ext/hash.rb +8 -0
- data/lib/active_support/core_ext/module/aliasing.rb +74 -0
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +58 -0
- data/lib/active_support/core_ext/module.rb +16 -0
- data/lib/active_support/core_ext/object/conversions.rb +14 -0
- data/lib/active_support/core_ext/object/extending.rb +80 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +74 -0
- data/lib/active_support/core_ext/object/metaclass.rb +13 -0
- data/lib/active_support/core_ext/object/misc.rb +43 -0
- data/lib/active_support/core_ext/object.rb +5 -0
- data/lib/active_support/core_ext/string/inflections.rb +167 -0
- data/lib/active_support/core_ext/string.rb +7 -0
- data/lib/active_support/core_ext.rb +4 -0
- data/lib/active_support/inflections.rb +55 -0
- data/lib/active_support/inflector.rb +348 -0
- data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
- data/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
- data/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
- data/lib/active_support/vendor.rb +14 -0
- data/lib/active_support.rb +6 -0
- data/spec/case/association_test.rb +97 -0
- data/spec/case/base_test.rb +74 -0
- data/spec/case/callbacks_observers_test.rb +38 -0
- data/spec/case/callbacks_test.rb +424 -0
- data/spec/case/serialization_test.rb +87 -0
- data/spec/case/validations_test.rb +1482 -0
- data/spec/data.tch +0 -0
- data/spec/helper.rb +15 -0
- data/spec/light_cloud.yml +18 -0
- data/spec/model/account.rb +4 -0
- data/spec/model/topic.rb +26 -0
- data/spec/model/user.rb +8 -0
- metadata +173 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Hash #:nodoc:
|
4
|
+
module Keys
|
5
|
+
# Return a new hash with all keys converted to strings.
|
6
|
+
def stringify_keys
|
7
|
+
inject({}) do |options, (key, value)|
|
8
|
+
options[key.to_s] = value
|
9
|
+
options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Destructively convert all keys to strings.
|
14
|
+
def stringify_keys!
|
15
|
+
keys.each do |key|
|
16
|
+
self[key.to_s] = delete(key)
|
17
|
+
end
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return a new hash with all keys converted to symbols.
|
22
|
+
def symbolize_keys
|
23
|
+
inject({}) do |options, (key, value)|
|
24
|
+
options[(key.to_sym rescue key) || key] = value
|
25
|
+
options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Destructively convert all keys to symbols.
|
30
|
+
def symbolize_keys!
|
31
|
+
self.replace(self.symbolize_keys)
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :to_options, :symbolize_keys
|
35
|
+
alias_method :to_options!, :symbolize_keys!
|
36
|
+
|
37
|
+
# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
|
38
|
+
# Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols
|
39
|
+
# as keys, this will fail.
|
40
|
+
#
|
41
|
+
# ==== Examples:
|
42
|
+
# { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
|
43
|
+
# { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age"
|
44
|
+
# { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
45
|
+
def assert_valid_keys(*valid_keys)
|
46
|
+
unknown_keys = keys - [valid_keys].flatten
|
47
|
+
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module CoreExtensions
|
3
|
+
module Module
|
4
|
+
# Encapsulates the common pattern of:
|
5
|
+
#
|
6
|
+
# alias_method :foo_without_feature, :foo
|
7
|
+
# alias_method :foo, :foo_with_feature
|
8
|
+
#
|
9
|
+
# With this, you simply do:
|
10
|
+
#
|
11
|
+
# alias_method_chain :foo, :feature
|
12
|
+
#
|
13
|
+
# And both aliases are set up for you.
|
14
|
+
#
|
15
|
+
# Query and bang methods (foo?, foo!) keep the same punctuation:
|
16
|
+
#
|
17
|
+
# alias_method_chain :foo?, :feature
|
18
|
+
#
|
19
|
+
# is equivalent to
|
20
|
+
#
|
21
|
+
# alias_method :foo_without_feature?, :foo?
|
22
|
+
# alias_method :foo?, :foo_with_feature?
|
23
|
+
#
|
24
|
+
# so you can safely chain foo, foo?, and foo! with the same feature.
|
25
|
+
def alias_method_chain(target, feature)
|
26
|
+
# Strip out punctuation on predicates or bang methods since
|
27
|
+
# e.g. target?_without_feature is not a valid method name.
|
28
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
29
|
+
yield(aliased_target, punctuation) if block_given?
|
30
|
+
|
31
|
+
with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
|
32
|
+
|
33
|
+
alias_method without_method, target
|
34
|
+
alias_method target, with_method
|
35
|
+
|
36
|
+
case
|
37
|
+
when public_method_defined?(without_method)
|
38
|
+
public target
|
39
|
+
when protected_method_defined?(without_method)
|
40
|
+
protected target
|
41
|
+
when private_method_defined?(without_method)
|
42
|
+
private target
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Allows you to make aliases for attributes, which includes
|
47
|
+
# getter, setter, and query methods.
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
#
|
51
|
+
# class Content < AntMapper::Base
|
52
|
+
# # has a title attribute
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# class Email < Content
|
56
|
+
# alias_attribute :subject, :title
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# e = Email.find(1)
|
60
|
+
# e.title # => "Superstars"
|
61
|
+
# e.subject # => "Superstars"
|
62
|
+
# e.subject? # => true
|
63
|
+
# e.subject = "Megastars"
|
64
|
+
# e.title # => "Megastars"
|
65
|
+
def alias_attribute(new_name, old_name)
|
66
|
+
module_eval <<-STR, __FILE__, __LINE__+1
|
67
|
+
def #{new_name}; self.#{old_name}; end
|
68
|
+
def #{new_name}?; self.#{old_name}?; end
|
69
|
+
def #{new_name}=(v); self.#{old_name} = v; end
|
70
|
+
STR
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Module
|
2
|
+
# Declare an attribute accessor with an initial default return value.
|
3
|
+
#
|
4
|
+
# To give attribute <tt>:age</tt> the initial value <tt>25</tt>:
|
5
|
+
#
|
6
|
+
# class Person
|
7
|
+
# attr_accessor_with_default :age, 25
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# some_person.age
|
11
|
+
# => 25
|
12
|
+
# some_person.age = 26
|
13
|
+
# some_person.age
|
14
|
+
# => 26
|
15
|
+
#
|
16
|
+
# To give attribute <tt>:element_name</tt> a dynamic default value, evaluated
|
17
|
+
# in scope of self:
|
18
|
+
#
|
19
|
+
# attr_accessor_with_default(:element_name) { name.underscore }
|
20
|
+
#
|
21
|
+
def attr_accessor_with_default(sym, default = nil, &block)
|
22
|
+
raise 'Default value or block required' unless !default.nil? || block
|
23
|
+
define_method(sym, block_given? ? block : Proc.new { default })
|
24
|
+
module_eval(<<-EVAL, __FILE__, __LINE__)
|
25
|
+
def #{sym}=(value)
|
26
|
+
class << self; attr_reader :#{sym} end
|
27
|
+
@#{sym} = value
|
28
|
+
end
|
29
|
+
EVAL
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Extends the module object with module and instance accessors for class attributes,
|
2
|
+
# just like the native attr* accessors for instance attributes.
|
3
|
+
#
|
4
|
+
# module AppConfiguration
|
5
|
+
# mattr_accessor :google_api_key
|
6
|
+
# self.google_api_key = "123456789"
|
7
|
+
#
|
8
|
+
# mattr_accessor :paypal_url
|
9
|
+
# self.paypal_url = "www.sandbox.paypal.com"
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# AppConfiguration.google_api_key = "overriding the api key!"
|
13
|
+
class Module
|
14
|
+
def mattr_reader(*syms)
|
15
|
+
syms.each do |sym|
|
16
|
+
next if sym.is_a?(Hash)
|
17
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
18
|
+
unless defined? @@#{sym}
|
19
|
+
@@#{sym} = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.#{sym}
|
23
|
+
@@#{sym}
|
24
|
+
end
|
25
|
+
|
26
|
+
def #{sym}
|
27
|
+
@@#{sym}
|
28
|
+
end
|
29
|
+
EOS
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def mattr_writer(*syms)
|
34
|
+
options = syms.extract_options!
|
35
|
+
syms.each do |sym|
|
36
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
37
|
+
unless defined? @@#{sym}
|
38
|
+
@@#{sym} = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.#{sym}=(obj)
|
42
|
+
@@#{sym} = obj
|
43
|
+
end
|
44
|
+
|
45
|
+
#{"
|
46
|
+
def #{sym}=(obj)
|
47
|
+
@@#{sym} = obj
|
48
|
+
end
|
49
|
+
" unless options[:instance_writer] == false }
|
50
|
+
EOS
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def mattr_accessor(*syms)
|
55
|
+
mattr_reader(*syms)
|
56
|
+
mattr_writer(*syms)
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
2
|
+
require 'active_support/core_ext/module/attr_accessor_with_default'
|
3
|
+
require 'active_support/core_ext/module/aliasing'
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
module CoreExtensions
|
7
|
+
# Various extensions for the Ruby core Module class.
|
8
|
+
module Module
|
9
|
+
# Nothing here. Only defined for API documentation purposes.
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Module
|
15
|
+
include ActiveSupport::CoreExtensions::Module
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Object
|
2
|
+
# Alias of <tt>to_s</tt>.
|
3
|
+
def to_param
|
4
|
+
to_s
|
5
|
+
end
|
6
|
+
|
7
|
+
# Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
|
8
|
+
# param name.
|
9
|
+
#
|
10
|
+
# Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
|
11
|
+
def to_query(key)
|
12
|
+
"#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class Object
|
2
|
+
def remove_subclasses_of(*superclasses) #:nodoc:
|
3
|
+
Class.remove_class(*subclasses_of(*superclasses))
|
4
|
+
end
|
5
|
+
|
6
|
+
begin
|
7
|
+
ObjectSpace.each_object(Class.new) {}
|
8
|
+
|
9
|
+
# Exclude this class unless it's a subclass of our supers and is defined.
|
10
|
+
# We check defined? in case we find a removed class that has yet to be
|
11
|
+
# garbage collected. This also fails for anonymous classes -- please
|
12
|
+
# submit a patch if you have a workaround.
|
13
|
+
def subclasses_of(*superclasses) #:nodoc:
|
14
|
+
subclasses = []
|
15
|
+
|
16
|
+
superclasses.each do |sup|
|
17
|
+
ObjectSpace.each_object(class << sup; self; end) do |k|
|
18
|
+
if k != sup && (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
|
19
|
+
subclasses << k
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
subclasses
|
25
|
+
end
|
26
|
+
rescue RuntimeError
|
27
|
+
# JRuby and any implementations which cannot handle the objectspace traversal
|
28
|
+
# above fall back to this implementation
|
29
|
+
def subclasses_of(*superclasses) #:nodoc:
|
30
|
+
subclasses = []
|
31
|
+
|
32
|
+
superclasses.each do |sup|
|
33
|
+
ObjectSpace.each_object(Class) do |k|
|
34
|
+
if superclasses.any? { |superclass| k < superclass } &&
|
35
|
+
(k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
|
36
|
+
subclasses << k
|
37
|
+
end
|
38
|
+
end
|
39
|
+
subclasses.uniq!
|
40
|
+
end
|
41
|
+
subclasses
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def extended_by #:nodoc:
|
46
|
+
ancestors = class << self; ancestors end
|
47
|
+
ancestors.select { |mod| mod.class == Module } - [ Object, Kernel ]
|
48
|
+
end
|
49
|
+
|
50
|
+
def extend_with_included_modules_from(object) #:nodoc:
|
51
|
+
object.extended_by.each { |mod| extend mod }
|
52
|
+
end
|
53
|
+
|
54
|
+
unless defined? instance_exec # 1.9
|
55
|
+
module InstanceExecMethods #:nodoc:
|
56
|
+
end
|
57
|
+
include InstanceExecMethods
|
58
|
+
|
59
|
+
# Evaluate the block with the given arguments within the context of
|
60
|
+
# this object, so self is set to the method receiver.
|
61
|
+
#
|
62
|
+
# From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
|
63
|
+
def instance_exec(*args, &block)
|
64
|
+
begin
|
65
|
+
old_critical, Thread.critical = Thread.critical, true
|
66
|
+
n = 0
|
67
|
+
n += 1 while respond_to?(method_name = "__instance_exec#{n}")
|
68
|
+
InstanceExecMethods.module_eval { define_method(method_name, &block) }
|
69
|
+
ensure
|
70
|
+
Thread.critical = old_critical
|
71
|
+
end
|
72
|
+
|
73
|
+
begin
|
74
|
+
send(method_name, *args)
|
75
|
+
ensure
|
76
|
+
InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class Object
|
2
|
+
# Available in 1.8.6 and later.
|
3
|
+
unless respond_to?(:instance_variable_defined?)
|
4
|
+
def instance_variable_defined?(variable)
|
5
|
+
instance_variables.include?(variable.to_s)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# Returns a hash that maps instance variable names without "@" to their
|
10
|
+
# corresponding values. Keys are strings both in Ruby 1.8 and 1.9.
|
11
|
+
#
|
12
|
+
# class C
|
13
|
+
# def initialize(x, y)
|
14
|
+
# @x, @y = x, y
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
|
19
|
+
def instance_values #:nodoc:
|
20
|
+
instance_variables.inject({}) do |values, name|
|
21
|
+
values[name.to_s[1..-1]] = instance_variable_get(name)
|
22
|
+
values
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns an array of instance variable names including "@". They are strings
|
27
|
+
# both in Ruby 1.8 and 1.9.
|
28
|
+
#
|
29
|
+
# class C
|
30
|
+
# def initialize(x, y)
|
31
|
+
# @x, @y = x, y
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
36
|
+
if RUBY_VERSION >= '1.9'
|
37
|
+
def instance_variable_names
|
38
|
+
instance_variables.map { |var| var.to_s }
|
39
|
+
end
|
40
|
+
else
|
41
|
+
alias_method :instance_variable_names, :instance_variables
|
42
|
+
end
|
43
|
+
|
44
|
+
# Copies the instance variables of +object+ into +self+.
|
45
|
+
#
|
46
|
+
# Instance variable names in the +exclude+ array are ignored. If +object+
|
47
|
+
# responds to <tt>protected_instance_variables</tt> the ones returned are
|
48
|
+
# also ignored. For example, Rails controllers implement that method.
|
49
|
+
#
|
50
|
+
# In both cases strings and symbols are understood, and they have to include
|
51
|
+
# the at sign.
|
52
|
+
#
|
53
|
+
# class C
|
54
|
+
# def initialize(x, y, z)
|
55
|
+
# @x, @y, @z = x, y, z
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# def protected_instance_variables
|
59
|
+
# %w(@z)
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# a = C.new(0, 1, 2)
|
64
|
+
# b = C.new(3, 4, 5)
|
65
|
+
#
|
66
|
+
# a.copy_instance_variables_from(b, [:@y])
|
67
|
+
# # a is now: @x = 3, @y = 1, @z = 2
|
68
|
+
def copy_instance_variables_from(object, exclude = []) #:nodoc:
|
69
|
+
exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables
|
70
|
+
|
71
|
+
vars = object.instance_variables.map(&:to_s) - exclude.map(&:to_s)
|
72
|
+
vars.each { |name| instance_variable_set(name, object.instance_variable_get(name)) }
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Object
|
2
|
+
# Get object's meta (ghost, eigenclass, singleton) class
|
3
|
+
def metaclass
|
4
|
+
class << self
|
5
|
+
self
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# If class_eval is called on an object, add those methods to its metaclass
|
10
|
+
def class_eval(*args, &block)
|
11
|
+
metaclass.class_eval(*args, &block)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Object
|
2
|
+
# Returns +value+ after yielding +value+ to the block. This simplifies the
|
3
|
+
# process of constructing an object, performing work on the object, and then
|
4
|
+
# returning the object from a method. It is a Ruby-ized realization of the K
|
5
|
+
# combinator, courtesy of Mikael Brockman.
|
6
|
+
#
|
7
|
+
# ==== Examples
|
8
|
+
#
|
9
|
+
# # Without returning
|
10
|
+
# def foo
|
11
|
+
# values = []
|
12
|
+
# values << "bar"
|
13
|
+
# values << "baz"
|
14
|
+
# return values
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# foo # => ['bar', 'baz']
|
18
|
+
#
|
19
|
+
# # returning with a local variable
|
20
|
+
# def foo
|
21
|
+
# returning values = [] do
|
22
|
+
# values << 'bar'
|
23
|
+
# values << 'baz'
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# foo # => ['bar', 'baz']
|
28
|
+
#
|
29
|
+
# # returning with a block argument
|
30
|
+
# def foo
|
31
|
+
# returning [] do |values|
|
32
|
+
# values << 'bar'
|
33
|
+
# values << 'baz'
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# foo # => ['bar', 'baz']
|
38
|
+
def returning(value)
|
39
|
+
yield(value)
|
40
|
+
value
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module ActiveSupport #:nodoc:
|
4
|
+
module CoreExtensions #:nodoc:
|
5
|
+
module String #:nodoc:
|
6
|
+
# String inflections define new methods on the String class to transform names for different purposes.
|
7
|
+
# For instance, you can figure out the name of a database from the name of a class.
|
8
|
+
#
|
9
|
+
# "ScaleScore".tableize # => "scale_scores"
|
10
|
+
module Inflections
|
11
|
+
# Returns the plural form of the word in the string.
|
12
|
+
#
|
13
|
+
# "post".pluralize # => "posts"
|
14
|
+
# "octopus".pluralize # => "octopi"
|
15
|
+
# "sheep".pluralize # => "sheep"
|
16
|
+
# "words".pluralize # => "words"
|
17
|
+
# "the blue mailman".pluralize # => "the blue mailmen"
|
18
|
+
# "CamelOctopus".pluralize # => "CamelOctopi"
|
19
|
+
def pluralize
|
20
|
+
Inflector.pluralize(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
# The reverse of +pluralize+, returns the singular form of a word in a string.
|
24
|
+
#
|
25
|
+
# "posts".singularize # => "post"
|
26
|
+
# "octopi".singularize # => "octopus"
|
27
|
+
# "sheep".singularize # => "sheep"
|
28
|
+
# "word".singularize # => "word"
|
29
|
+
# "the blue mailmen".singularize # => "the blue mailman"
|
30
|
+
# "CamelOctopi".singularize # => "CamelOctopus"
|
31
|
+
def singularize
|
32
|
+
Inflector.singularize(self)
|
33
|
+
end
|
34
|
+
|
35
|
+
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
|
36
|
+
# is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
|
37
|
+
#
|
38
|
+
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
|
39
|
+
#
|
40
|
+
# "active_record".camelize # => "ActiveRecord"
|
41
|
+
# "active_record".camelize(:lower) # => "activeRecord"
|
42
|
+
# "active_record/errors".camelize # => "ActiveRecord::Errors"
|
43
|
+
# "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
|
44
|
+
def camelize(first_letter = :upper)
|
45
|
+
case first_letter
|
46
|
+
when :upper then Inflector.camelize(self, true)
|
47
|
+
when :lower then Inflector.camelize(self, false)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
alias_method :camelcase, :camelize
|
51
|
+
|
52
|
+
# Capitalizes all the words and replaces some characters in the string to create
|
53
|
+
# a nicer looking title. +titleize+ is meant for creating pretty output. It is not
|
54
|
+
# used in the Rails internals.
|
55
|
+
#
|
56
|
+
# +titleize+ is also aliased as +titlecase+.
|
57
|
+
#
|
58
|
+
# "man from the boondocks".titleize # => "Man From The Boondocks"
|
59
|
+
# "x-men: the last stand".titleize # => "X Men: The Last Stand"
|
60
|
+
def titleize
|
61
|
+
Inflector.titleize(self)
|
62
|
+
end
|
63
|
+
alias_method :titlecase, :titleize
|
64
|
+
|
65
|
+
# The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
|
66
|
+
#
|
67
|
+
# +underscore+ will also change '::' to '/' to convert namespaces to paths.
|
68
|
+
#
|
69
|
+
# "ActiveRecord".underscore # => "active_record"
|
70
|
+
# "ActiveRecord::Errors".underscore # => active_record/errors
|
71
|
+
def underscore
|
72
|
+
Inflector.underscore(self)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Replaces underscores with dashes in the string.
|
76
|
+
#
|
77
|
+
# "puni_puni" # => "puni-puni"
|
78
|
+
def dasherize
|
79
|
+
Inflector.dasherize(self)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Removes the module part from the constant expression in the string.
|
83
|
+
#
|
84
|
+
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
|
85
|
+
# "Inflections".demodulize # => "Inflections"
|
86
|
+
def demodulize
|
87
|
+
Inflector.demodulize(self)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
|
91
|
+
#
|
92
|
+
# ==== Examples
|
93
|
+
#
|
94
|
+
# class Person
|
95
|
+
# def to_param
|
96
|
+
# "#{id}-#{name.parameterize}"
|
97
|
+
# end
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# @person = Person.find(1)
|
101
|
+
# # => #<Person id: 1, name: "Donald E. Knuth">
|
102
|
+
#
|
103
|
+
# <%= link_to(@person.name, person_path %>
|
104
|
+
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
|
105
|
+
def parameterize
|
106
|
+
Inflector.parameterize(self)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Creates the name of a table like Rails does for models to table names. This method
|
110
|
+
# uses the +pluralize+ method on the last word in the string.
|
111
|
+
#
|
112
|
+
# "RawScaledScorer".tableize # => "raw_scaled_scorers"
|
113
|
+
# "egg_and_ham".tableize # => "egg_and_hams"
|
114
|
+
# "fancyCategory".tableize # => "fancy_categories"
|
115
|
+
def tableize
|
116
|
+
Inflector.tableize(self)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Create a class name from a plural table name like Rails does for table names to models.
|
120
|
+
# Note that this returns a string and not a class. (To convert to an actual class
|
121
|
+
# follow +classify+ with +constantize+.)
|
122
|
+
#
|
123
|
+
# "egg_and_hams".classify # => "EggAndHam"
|
124
|
+
# "posts".classify # => "Post"
|
125
|
+
#
|
126
|
+
# Singular names are not handled correctly.
|
127
|
+
#
|
128
|
+
# "business".classify # => "Busines"
|
129
|
+
def classify
|
130
|
+
Inflector.classify(self)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Capitalizes the first word, turns underscores into spaces, and strips '_id'.
|
134
|
+
# Like +titleize+, this is meant for creating pretty output.
|
135
|
+
#
|
136
|
+
# "employee_salary" # => "Employee salary"
|
137
|
+
# "author_id" # => "Author"
|
138
|
+
def humanize
|
139
|
+
Inflector.humanize(self)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Creates a foreign key name from a class name.
|
143
|
+
# +separate_class_name_and_id_with_underscore+ sets whether
|
144
|
+
# the method should put '_' between the name and 'id'.
|
145
|
+
#
|
146
|
+
# Examples
|
147
|
+
# "Message".foreign_key # => "message_id"
|
148
|
+
# "Message".foreign_key(false) # => "messageid"
|
149
|
+
# "Admin::Post".foreign_key # => "post_id"
|
150
|
+
def foreign_key(separate_class_name_and_id_with_underscore = true)
|
151
|
+
Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
|
152
|
+
end
|
153
|
+
|
154
|
+
# +constantize+ tries to find a declared constant with the name specified
|
155
|
+
# in the string. It raises a NameError when the name is not in CamelCase
|
156
|
+
# or is not initialized.
|
157
|
+
#
|
158
|
+
# Examples
|
159
|
+
# "Module".constantize # => Module
|
160
|
+
# "Class".constantize # => Class
|
161
|
+
def constantize
|
162
|
+
Inflector.constantize(self)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|