Wrapping a Ruby Method

Burdette Lamar - Nov 7 '21 - - Dev Community

You can "wrap" an instance (or singleton) method so that your wrapping method gets to act both before and after the wrapped method is called:

$ cat -n t.rb
     1  class Array
     2
     3    # Save the existing method.
     4    alias :old_initialize :initialize
     5
     6    # Define the wrapper method.
     7    def initialize(*args, &block)
     8      # Here's where we get to do a prelude.
     9      block_s = block ? block.inspect : 'no block'
    10      puts "Creating an array from #{args} and #{block_s}."
    11      # Make the call, saving the result.
    12      a = old_initialize(*args, &block)
    13      # Here's where we get to do a postlude.
    14      puts "Created #{a}."
    15      puts ''
    16      # And of course return the new array.
    17      a
    18    end
    19
    20  end
    21
    22  Array.new
    23  Array.new([])
    24  Array.new(4)
    25  Array.new(4, 'nosuch')
    26  Array.new(4) {|i| "Element #{i}"}
Enter fullscreen mode Exit fullscreen mode

The output:

Creating an array from [] and no block.
Created [].

Creating an array from [[]] and no block.
Created [].

Creating an array from [4] and no block.
Created [nil, nil, nil, nil].

Creating an array from [4, "nosuch"] and no block.
Created ["nosuch", "nosuch", "nosuch", "nosuch"].

Creating an array from [4] and #<Proc:0x000001e256eb3ab8 t.rb:26>.
Created ["Element 0", "Element 1", "Element 2", "Element 3"].

Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .