aboutsummaryrefslogtreecommitdiffstats
path: root/railties/guides/source/active_support_core_extensions.textile
diff options
context:
space:
mode:
authorXavier Noria <fxn@hashref.com>2009-10-27 00:11:22 +0100
committerXavier Noria <fxn@hashref.com>2009-10-27 00:11:22 +0100
commitf37c90a8758d4dc007ad6a3428769651981ea4f4 (patch)
tree41b0af00875a76c6002c3afc24e359d753c734b9 /railties/guides/source/active_support_core_extensions.textile
parentd226287855800e1eec58cd35ed3aac5cd9fbf630 (diff)
downloadrails-f37c90a8758d4dc007ad6a3428769651981ea4f4.tar.gz
rails-f37c90a8758d4dc007ad6a3428769651981ea4f4.tar.bz2
rails-f37c90a8758d4dc007ad6a3428769651981ea4f4.zip
AS guide: documents Proc#bind
Diffstat (limited to 'railties/guides/source/active_support_core_extensions.textile')
-rw-r--r--railties/guides/source/active_support_core_extensions.textile42
1 files changed, 41 insertions, 1 deletions
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index 2df46a332f..147366c1a6 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -1680,7 +1680,47 @@ The method +Range#overlaps?+ says whether any two given ranges have non-void int
h3. Extensions to +Proc+
-...
+h4. +bind+
+
+As you surely know Ruby has an +UnboundMethod+ class whose instances are methods that belong to the limbo of methods without a self. The method +Module#instance_method+ returns an unbound method for example:
+
+<ruby>
+Hash.instance_method(:delete) # => #<UnboundMethod: Hash#delete>
+</ruby>
+
+An unbound method is not callable as is, you need to bind it first to an object with +bind+:
+
+<ruby>
+clear = Hash.instance_method(:clear)
+clear.bind({:a => 1}).call # => {}
+</ruby>
+
+Active Support defines +Proc#bind+ with an analogous purpose:
+
+<ruby>
+Proc.new { size }.bind([]).call # => 0
+</ruby>
+
+As you see that's callable and bound to the argument, the return value is indeed a +Method+.
+
+NOTE: To do so +Proc#bind+ actually creates a method under the hood. If you ever see a method with a weird name like +__bind_1256598120_237302+ in a stack trace you know now where it comes from.
+
+Action Pack uses this trick in +rescue_from+ for example, which accepts the name of a method and also a proc as callbacks for a given rescued exception. It has to call them in either case, so a bound method is returned by +handler_for_rescue+, thus simplifying the code in the caller:
+
+<ruby>
+def handler_for_rescue(exception)
+ _, rescuer = Array(rescue_handlers).reverse.detect do |klass_name, handler|
+ ...
+ end
+
+ case rescuer
+ when Symbol
+ method(rescuer)
+ when Proc
+ rescuer.bind(self)
+ end
+end
+</ruby>
h3. Extensions to +Date+