From f37c90a8758d4dc007ad6a3428769651981ea4f4 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 27 Oct 2009 00:11:22 +0100 Subject: AS guide: documents Proc#bind --- .../source/active_support_core_extensions.textile | 42 +++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (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 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: + + +Hash.instance_method(:delete) # => # + + +An unbound method is not callable as is, you need to bind it first to an object with +bind+: + + +clear = Hash.instance_method(:clear) +clear.bind({:a => 1}).call # => {} + + +Active Support defines +Proc#bind+ with an analogous purpose: + + +Proc.new { size }.bind([]).call # => 0 + + +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: + + +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 + h3. Extensions to +Date+ -- cgit v1.2.3