File: facade.rb

package info (click to toggle)
ruby-facade 1.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 128 kB
  • sloc: ruby: 66; makefile: 4
file content (50 lines) | stat: -rw-r--r-- 1,394 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# frozen_string_literal: true

module Facade
  # The version of the facade library
  FACADE_VERSION = '1.2.2'

  # The facade method will forward a singleton method as an instance
  # method of the extending class. If no arguments are provided, then all
  # singleton methods of the class or module become instance methods.
  #
  # Existing instance methods are NOT overridden, but are instead ignored.
  #
  # Example:
  #
  #  require 'facade'
  #
  #  class MyString < String
  #    extend Facade
  #    facade File, :dirname, :basename
  #  end
  #
  #  s = MyString.new('/home/djberge')
  #  s.basename # => 'djberge'
  #  s.dirname  # => '/home'
  #
  def facade(klass, *methods)
    methods = methods.flatten

    if methods.empty? # Default to all methods
      methods = klass.is_a?(Class) ? klass.methods(false) : klass.public_instance_methods(false)
    end

    methods -= instance_methods.map(&:to_sym) # No clobber

    # Cache the extended object for modules to avoid creating it on every call
    mod_proxy = klass.is_a?(Module) && !klass.is_a?(Class) ? Object.new.extend(klass) : nil

    methods.each do |method_name|
      define_method(method_name) do
        meth = klass.is_a?(Class) ? klass.method(method_name) : mod_proxy.method(method_name)

        if meth.arity.zero?
          meth.call
        else
          meth.call(self)
        end
      end
    end
  end
end