rubymetaprogrammingalias-method

alias_method and class_methods don't mix?


I've been trying to tinker with a global Cache module, but I can't figure out why this isn't working.

Does anyone have any suggestions?

This is the error:

NameError: undefined method `get' for module `Cache'
    from (irb):21:in `alias_method'

... generated by this code:

module Cache
  def self.get
    puts "original"
  end
end

module Cache
  def self.get_modified
    puts "New get"
  end
end

def peek_a_boo
  Cache.module_eval do
    # make :get_not_modified
    alias_method :get_not_modified, :get
    alias_method :get, :get_modified
  end

  Cache.get

  Cache.module_eval do
    alias_method :get, :get_not_modified
  end
end

# test first round
peek_a_boo

# test second round
peek_a_boo

Solution

  • The calls to alias_method will attempt to operate on instance methods. There is no instance method named get in your Cache module, so it fails.

    Because you want to alias class methods (methods on the metaclass of Cache), you would have to do something like:

    class << Cache  # Change context to metaclass of Cache
      alias_method :get_not_modified, :get
      alias_method :get, :get_modified
    end
    
    Cache.get
    
    class << Cache  # Change context to metaclass of Cache
      alias_method :get, :get_not_modified
    end