Unalias a method?


#1

I needed to alias a method (alias_method) to change its behavior during
a series of tests the other day. I was able to alias the Module’s
method ok, but I couldn’t figure out how to unalias it when I was done.

What’s the technique to unalias a method that has been aliased?

Thanks.


#2

Todd B. wrote:

What’s the technique to unalias a method that has been aliased?

class Foo
def hello
p “hi”
end
alias_method :hello2, :hello
end

Foo.new.hello2 #=> “hi”
class Foo
remove_method :hello2
end
Foo.new.hello2 #=> undefined method `hello2’


#3

On Sun, Jan 25, 2009 at 2:55 PM, Todd B. removed_email_address@domain.invalid
wrote:

I’m assuming that alias_method is what I need to be using to temporarily
“redirect” all my Foo.hello calls to do something different for a
certain period of time, and finally I want to revert to the original
behavior of Foo.hello.

I used a module example, because that’s what I’m using my real case, and
I don’t have access to the module source.

Hopefully this does what you’d expect. -greg

module Foo
extend self

def hello
p “Hi”
end
end

Foo.hello

module Foo
alias_method :old_hello, :hello

def hello
p “Hello again”
end
end

Foo.hello

module Foo
alias_method :hello, :old_hello
end

Foo.hello


#4

Mike G. wrote:

class Foo
def hello
p “hi”
end
alias_method :hello2, :hello
end

Foo.new.hello2 #=> “hi”
class Foo
remove_method :hello2
end
Foo.new.hello2 #=> undefined method `hello2’

Thanks Mike. Perhaps that’s what I said, but that’s not what I meant…
:wink: Sorry about that. I tried recreating my scenario with
alias_method, and it seems as if it wasn’t really a factor in my test.

This is the sequence that I would like to happen:

module Foo
def Foo.hello
p “Hi”
end
end # module

####################

p “I expect to print hi:”
Foo.hello #<== this works

####################

module Foo
def Foo.hello
p “printing of hi is suppressed”
end
end

####################

p “I expect to suppress printing of hi:”
Foo.hello # <== this works

####################

p “Now, I want to print hi again:”

###??? What needs to happen here?

Foo.hello

I’m assuming that alias_method is what I need to be using to temporarily
“redirect” all my Foo.hello calls to do something different for a
certain period of time, and finally I want to revert to the original
behavior of Foo.hello.

I used a module example, because that’s what I’m using my real case, and
I don’t have access to the module source.

Thanks, Todd


#5

On Jan 25, 2009, at 05:48 , Todd B. wrote:

What’s the technique to unalias a method that has been aliased?

alias the old method back. A really messy example of this is heckle
where we replace methods over and over and then alias the original
back into place.


#6

Hopefully this does what you’d expect. -greg

Hey Greg! That works great from Terminal - thanks.

I changed your example to work with Sketchup, and by writing it like
this, I got it work under Sketchup as I want:

(The UI.messagebox put up a dialog box, similar to a javascript alert()
box )

require ‘sketchup.rb’ ;
include UI # <== this is the key to getting this to work

messagebox “Regular Messagebox…” ;

module UI
extend self
alias_method :messagebox_old, :messagebox

def messagebox (string)
puts “aliased method: #{string}”
end
end

messagebox “this should show up in the console” ;

module UI
alias_method :messagebox, :messagebox_old
end

messagebox “Back to normal” ;

In the above case, I get a popup, then a message to the Ruby console,
then a popup. Perfect.
However, from all my code, I typically never “include UI” and write
scripts like thi, qualifying the messagebox method with UI.messagebox…

require ‘sketchup.rb’ ;

UI.messagebox “Regular Messagebox…” ;

module UI
extend self
alias_method :messagebox_old, :messagebox

def messagebox (string)
puts “aliased method: #{string}”
end
end

UI.messagebox “this should show up in the console” ;

module UI
alias_method :messagebox, :messagebox_old
end

UI.messagebox “Back to normal” ;

Adding the UI. qualifier, the aliased method is never called and I get 3
popups.
Any ideas?


#7

Todd B. wrote:

I’m assuming that alias_method is what I need to be using to temporarily
“redirect” all my Foo.hello calls to do something different for a
certain period of time, and finally I want to revert to the original
behavior of Foo.hello.

In that case, maybe push/pop would make things easier.

module MethodStack
class << self
def included(includer)
stack = Hash.new

  define_method(:push_method) { |method_name, &block|
    unless stack.has_key?(method_name)
      stack[method_name] = [instance_method(method_name)]
    end
    stack[method_name].push(block)
    define_method(method_name, &block)
  }

  define_method(:pop_method) { |method_name|
    stack[method_name].pop
    define_method(method_name, stack[method_name].last)
  }
end

end
end

class Foo
class << self
include MethodStack
end
def hello
p “original hello”
end
end

obj = Foo.new
obj.hello # => “original hello”

class Foo
push_method(:hello) {
p “replacement hello”
}
end

obj.hello # => “replacement hello”
Foo.pop_method(:hello)
obj.hello # => “original hello”


#8

Mike G. wrote:

In that case, maybe push/pop would make things easier.

Didn’t work.

todd-burchs-computer:myruby toddburch$ ruby pushpop.rb
pushpop.rb:6: syntax error, unexpected tAMPER, expecting ‘|’
define_method(:push_method) { |method_name, &block|
^
pushpop.rb:12: syntax error, unexpected ‘}’, expecting kEND
}
^
todd-burchs-computer:myruby toddburch$


#9

Mike G. wrote:

The |&block| syntax is supported on 1.8.7+. Rewriting MethodStack for
1.8.6 is left as an exercise.

I had to laugh out loud on that one. Thanks Mike!


#10

Todd B. wrote:

Mike G. wrote:

In that case, maybe push/pop would make things easier.

Didn’t work.

todd-burchs-computer:myruby toddburch$ ruby pushpop.rb
pushpop.rb:6: syntax error, unexpected tAMPER, expecting ‘|’
define_method(:push_method) { |method_name, &block|
^
pushpop.rb:12: syntax error, unexpected ‘}’, expecting kEND
}
^
todd-burchs-computer:myruby toddburch$

The |&block| syntax is supported on 1.8.7+. Rewriting MethodStack for
1.8.6 is left as an exercise.


#11

Todd B. wrote:

Mike G. wrote:

The |&block| syntax is supported on 1.8.7+. Rewriting MethodStack for
1.8.6 is left as an exercise.

I had to laugh out loud on that one. Thanks Mike!

My last comment sounded more glib than intended. Since I’ve already
used MethodStack in my own code, I think it can be generally useful in
cleaning up repetitive alias_method calls.

I might try submitting it to facets, with two changes: change names to
push_instance_method/pop_instance_method for symmetry with
Module#instance_method, and add 1.8.6 compatibility.