Module: Corefines::Module::AliasMethodChain

Defined in:
lib/corefines/module.rb

Instance Method Summary collapse

Instance Method Details

#alias_method_chain(target, feature) ⇒ self

Encapsulates the common pattern of:

alias_method :meth_without_feature, :meth
alias_method :meth, :meth_with_feature

With this, you simply do:

alias_method_chain :meth, :feature

for example:

class ChainExample
  def say
    "hello"
  end
  def say_with_accent
    "helloo!"
  end
  alias_method_chain :say, :accent
end

and both aliases are set up for you:

example = ChainExample.new
example.say #=> "helloo!"
example.say_without_accent #=> "hello"

Query and bang methods (foo?, foo!) keep the same punctuation:

alias_method_chain :say!, :accent

is equivalent to:

alias_method :say_without_accent!, :say!
alias_method :say!, :say_with_accent!

so you can safely chain foo, foo?, and foo! with the same feature.

Parameters:

  • target (Symbol)

    name of the method to alias.

  • feature (Symbol)

    suffix for the aliases.

Returns:

  • (self)

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/corefines/module.rb', line 67

module AliasMethodChain
  refine ::Module do
    def alias_method_chain(target, feature)
      # Strip out punctuation on predicates, bang or writer methods since
      # e.g. target?_without_feature is not a valid method name.
      aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1

      with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
      without_method = "#{aliased_target}_without_#{feature}#{punctuation}"

      alias_method without_method, target
      alias_method target, with_method

      if public_method_defined? without_method
        public target
      elsif protected_method_defined? without_method
        protected target
      elsif private_method_defined? without_method
        private target
      end

      self
    end
  end
end