Removing Instance Methods

B

Brian Takita

Hello,

How can I remove a method from an instance?

For example, I set a method by doing:

#----------
a = 'one'
def a.one
1
end
#----------

Now how would I undefine a.one?

undef a.one
give a syntax error.

Thank you,
Brian Takita
 
C

Charles Steinman

Brian said:
Hello,

How can I remove a method from an instance?

For example, I set a method by doing:

#----------
a = 'one'
def a.one
1
end
#----------

Now how would I undefine a.one?

class << a
remove_method :eek:ne
end
 
G

Ghislain Mary

Hi,

Brian Takita a =E9crit :
Hello,
=20
How can I remove a method from an instance?
=20
For example, I set a method by doing:
=20
#----------
a =3D 'one'
def a.one
1
end
#----------
=20
Now how would I undefine a.one?
=20
undef a.one
give a syntax error.
=20
Thank you,
Brian Takita
=20

You can do something like:

class <<a
remove_method:)one)
end

But maybe there's a simpler way to do this...

HTH

Ghislain
 
B

Brian Takita

But maybe there's a simpler way to do this...
Is there? It seems like there should be a way to do this without
resorting to an eval statement?

How does Ruby itself remove methods when parsing remove_method?
 
C

Charles Steinman

Brian said:
Is there? It seems like there should be a way to do this without
resorting to an eval statement?

The code snippets offered don't use eval. They open the object's
singleton class and remove the method. There isn't really any more
straightforward way (since that is exactly what you want to do). If you
want to do it more concisely, you could add a remove_method to Object
that does this internally.
How does Ruby itself remove methods when parsing remove_method?

Looking at eval.c, it looks like it just deletes the method from the
class' method table.
 
B

Brian Takita

I'm sorry about the nonexistant explanation.

In this situation, the only solution that I know of is to use an eval.

def custom_remove_method(object, symbol)
remove_method_script = %-
class << object
remove_method:)#{symbol.to_s})
end
-
eval remove_method_script
end
Looking at eval.c, it looks like it just deletes the method from the class' method table.
Can this be done in Ruby?

Thank you,
Brian Takita
 
K

Kent Sibilev

Like this,

def custom_remove_method(object, symbol)
class << object
remove_method(symbol.to_sym)
end
end
 
B

Brian Takita

I get the following error when running this:
in `custom_remove_method': undefined local variable or method `symbol' for #<Class:#<String:0x27b7bb0>> (NameError)

Unfortunately, I can't figure out how to get the block to recognize the
symbol variable in the method.
I tried this:

def custom_remove_method(obj, sym)
obj.instance_variable_set:)@symbol_to_be_removed, obj)
class << obj
remove_method(@symbol_to_be_removed)
remove_instance_variable:)@symbol_to_be_removed)
end
end

but got this error:
warning: instance variable @symbol_to_be_removed not initialized
in `remove_method': nil is not a symbol (TypeError)
at the remove_method(@symbol_to_be_removed) statement.

Even if this hack works, it can possibly cause name clashes at some
level and won't work in a multithreaded environment.

Is there a better approach to getting the class block to recognize the
variable from the outside?
 
T

ts

B> def custom_remove_method(obj, sym)
B> obj.instance_variable_set:)@symbol_to_be_removed, obj)
B> class << obj
B> remove_method(@symbol_to_be_removed)
B> remove_instance_variable:)@symbol_to_be_removed)
B> end
B> end

moulon% cat b.rb
#!/usr/bin/ruby
def custom_remove_method(obj, sym)
class << obj; self end.send:)remove_method, sym)
end
class << a = []
def un
puts 1
end
end
a.un
custom_remove_method(a, :un)
a.un
moulon%

moulon% ./b.rb
1
/b.rb:12: undefined method `un' for []:Array (NoMethodError)
moulon%



Guy Decoux
 
K

Kent Sibilev

Yeah, you're right. I should have tested it first before posting :)

Kent.

=20
B> def custom_remove_method(obj, sym)
B> obj.instance_variable_set:)@symbol_to_be_removed, obj)
B> class << obj
B> remove_method(@symbol_to_be_removed)
B> remove_instance_variable:)@symbol_to_be_removed)
B> end
B> end
=20
moulon% cat b.rb
#!/usr/bin/ruby
def custom_remove_method(obj, sym)
class << obj; self end.send:)remove_method, sym)
end
class << a =3D []
def un
puts 1
end
end
a.un
custom_remove_method(a, :un)
a.un
moulon%
=20
moulon% ./b.rb
1
./b.rb:12: undefined method `un' for []:Array (NoMethodError)
moulon%
=20
=20
=20
Guy Decoux
=20
 
B

Brian Takita

This is a good way to get rid of those pesky 'method redefined'
warnings in cases such as in this case:

def a_method(obj)
def obj.one
'one'
end
end

def a_method2(obj)
def obj.one
1
end
end

one = 'one'
a_method(one)
a_method2(one)
warning: redefine one

###########
def custom_remove_method(obj, sym)
class << obj; self end.send:)remove_method, sym)
end

def a_method(obj)
custom_remove_method(obj, :eek:ne) if obj.respond_to?:)one)
def obj.one
'one'
end
end

def a_method2(obj)
custom_remove_method(obj, :eek:ne) if obj.respond_to?:)one)
def obj.one
1
end
end

one = 'one'
a_method(one)
a_method2(one)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,174
Latest member
BlissKetoACV
Top