From 11f6795b238172c4a13176062bd38b83285799b7 Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Sat, 29 Oct 2011 18:03:35 -0700
Subject: defines Module#qualified_const_(defined?|get|set) and
 String#deconstantize

This commit also implements a faster version of #demodulize I was unable
to isolate with git add --patch.

Not a big fan of the name #deconstantize. It complements #demodulize
getting rid of the rightmost constant, hence the name, but it is
unrelated to the well-known #constantize. So unsure. Could not come
with anything better, please feel free to rename.
---
 .../source/active_support_core_extensions.textile  | 83 ++++++++++++++++++++++
 1 file changed, 83 insertions(+)

(limited to 'railties/guides/source/active_support_core_extensions.textile')

diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index c04e49281e..0941953d1c 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -725,6 +725,64 @@ WARNING: This method returns precise results in Ruby 1.9. In older versions of R
 
 NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
 
+h5. Qualified Constant Names
+
+The standard methods +const_defined?+, +const_get+ , and +const_set+ accept
+bare constant names. Active Support extends this API to be able to pass
+relative qualified constant reference expressions.
+
+The new methods are +qualified_const_defined?+, +qualified_const_get+, and
++qualified_const_set+. Their arguments are assumed to be qualified constant
+names relative to their receiver:
+
+<ruby>
+Object.qualified_const_defined?("Math::PI")       # => true
+Object.qualified_const_get("Math::PI")            # => 3.141592653589793
+Object.qualified_const_set("Math::Phi", 1.618034) # => 1.618034
+</ruby>
+
+Arguments may be bare constant names:
+
+<ruby>
+Math.qualified_const_get("E") # => 2.718281828459045
+</ruby>
+
+These methods are analogous to their builtin counterparts. In particular,
++qualified_constant_defined?+ accepts an optional second argument in 1.9
+to be able to say whether you want the predicate to look in the ancestors.
+This flag is taken into account for each constant in the expression while
+walking down the path.
+
+For example, given
+
+<ruby>
+module M
+  X = 1
+end
+
+module N
+  class C
+    include M
+  end
+end
+</ruby>
+
++qualified_const_defined?+ behaves this way:
+
+<ruby>
+N.qualified_const_defined?("C::X", false) # => false (1.9 only)
+N.qualified_const_defined?("C::X", true)  # => true (1.9 only)
+N.qualified_const_defined?("C::X")        # => false in 1.8, true in 1.9
+</ruby>
+
+As the last example implies, in 1.9 the second argument defaults to true,
+as in +const_defined?+.
+
+For coherence with the builtin methods only relative paths are accepted.
+Absolute qualified constant names like +::Math::PI+ raise +NameError+.
+
+NOTE: Defined in +active_support/core_ext/module/qualified_const.rb+.
+
 h4. Synchronization
 
 The +synchronize+ macro declares a method to be synchronized:
@@ -1620,6 +1678,31 @@ end
 
 NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
 
+h5. +deconstantize+
+
+Given a string with a qualified constant reference expression, +deconstantize+ removes the rightmost segment, generally leaving the name of the constant's container:
+
+<ruby>
+"Product".deconstantize                        # => ""
+"Backoffice::UsersController".deconstantize    # => "Backoffice"
+"Admin::Hotel::ReservationUtils".deconstantize # => "Admin::Hotel"
+</ruby>
+
+Active Support for example uses this method in +Module#qualified_const_set+:
+
+<ruby>
+def qualified_const_set(path, value)
+  QualifiedConstUtils.raise_if_absolute(path)
+
+  const_name = path.demodulize
+  mod_name = path.deconstantize
+  mod = mod_name.empty? ? self : qualified_const_get(mod_name)
+  mod.const_set(const_name, value)
+end
+</ruby>
+
+NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
+
 h5. +parameterize+
 
 The method +parameterize+ normalizes its receiver in a way that can be used in pretty URLs.
-- 
cgit v1.2.3

