How to remove a method from an object?

hello everyone,

how can I remove a method from an object, without impacting future
instances of its class ?

say:

class Server
   def print
       puts 'hello'
   end
end

s1 = Server.new
s1.print #this work

#now remove print from s1 somehow..

s1.print #this should hit method_missing

s2 = Server.new
s2.print # this should work fine as well...

Thanks for any help

class Server
  attr_accessor :shh

  def initialize(f=false)
    @shh = f
  end

  def print
    if @shh
      self.send(:method_missing)
    else
      puts 'hi there'
    end
  end

  def method_missing
    puts 'I look forward to seeing better ways of doing this!'
  end

···

#
end

s = Server.new
s.print

s2 = Server.new(true)
s2.print

s.print

On Jan 10, 12:32 am, Valerio Schiavoni <valerio.schiav...@gmail.com> wrote:

hello everyone,

how can I remove a method from an object, without impacting future
instances of its class ?

say:

class Server
def print
puts 'hello'
end
end

s1 = Server.new
s1.print #this work

#now remove print from s1 somehow..

s1.print #this should hit method_missing

s2 = Server.new
s2.print # this should work fine as well...

Thanks for any help

the method is defined in the class, if you remove it, others will be affected.

try using singleton_method instead...(and yes, you can remove
singleton methods w your hearts content; but since these methods
belong to a particular object, you might not even bother removing..
:slight_smile:

kind regards -botp

···

On Jan 10, 2008 4:35 PM, Valerio Schiavoni <valerio.schiavoni@gmail.com> wrote:

how can I remove a method from an object, without impacting future
instances of its class ?

Alle giovedì 10 gennaio 2008, Valerio Schiavoni ha scritto:

hello everyone,

how can I remove a method from an object, without impacting future
instances of its class ?

say:

class Server
   def print
       puts 'hello'
   end
end

s1 = Server.new
s1.print #this work

#now remove print from s1 somehow..

s1.print #this should hit method_missing

s2 = Server.new
s2.print # this should work fine as well...

Thanks for any help

This should work:

class Server
   def print
       puts "hello from #{object_id}"
   end
end

s1 = Server.new
s1.print

class << s1
  undef_method :print
end

s2 = Server.new
s2.print
begin s1.print
rescue NoMethodError
  puts "undefined method 'print' for #{s1.object_id}"
end

=>
hello from -605995538
hello from -605995648
undefined method 'print' for -605995538

As you can see from the ids displayed by the print method, after removing the
method from the singleton class of s1, only the call to s2.print works; the
call to s1.print raises a NoMethodError exception.

I hope this helps

Stefano

ah, undef_,

how does it compare then if i do,
class << s1
  remove_method :print
end

i mean will undef_ do a remove or what?

but anyway, that is cool Stefano. thanks for the new i've just learned.

kind regards -botp

···

On Jan 10, 2008 6:12 PM, Stefano Crocco <stefano.crocco@alice.it> wrote:

class << s1
  undef_method :print
end

Brian.LeRoux ha scritto:

class Server
  attr_accessor :shh

  def initialize(f=false)
    @shh = f
  end

  def print
    if @shh
      self.send(:method_missing)
    else
      puts 'hi there'
    end
  end

  def method_missing
    puts 'I look forward to seeing better ways of doing this!'
  end
  #
end

s = Server.new
s.print

s2 = Server.new(true)
s2.print

s.print

> hello everyone,
>
> how can I remove a method from an object, without impacting future
> instances of its class ?
>
> say:
>
> class Server
> � �def print
> � � � �puts 'hello'
> � �end
> end
>
> s1 = Server.new
> s1.print #this work
>
> #now remove print from s1 somehow..
>
> s1.print #this should hit method_missing
>
> s2 = Server.new
> s2.print # this should work fine as well...
>
> Thanks for any help

Maybe it is not what the original post asked for, but I could not
resist...

class Server
  def initialize(add_print_method=false)
    if (add_print_method)
      def self.print
  puts "Hi #{self.object_id.to_s(16)}";
      end
    end

    puts "Object #{self.object_id.to_s(16)} created"
  end
end

a=Server.new(true)
b=Server.new

a.print # prints "Hi ..."
b.print # raises NoMethodError

···

On Jan 10, 12:32�am, Valerio Schiavoni <valerio.schiav...@gmail.com> > wrote:

Alle giovedì 10 gennaio 2008, botp ha scritto:

> class << s1
> undef_method :print
> end

ah, undef_,

how does it compare then if i do,
class << s1
  remove_method :print
end

i mean will undef_ do a remove or what?

but anyway, that is cool Stefano. thanks for the new i've just learned.

kind regards -botp

Well, in general remove_method will remove it only from the class where it's
called. If a superclass defines the same method, the superclass's method will
be called. According to ri, instead, undef_method, prevents the class from
responding to the method at all. Here's an example showing the difference

class A
  def test
    puts "test for class A"
  end
end

class B < A
  def test
    puts "test for class B"
  end
end

b = B.new
b.test
=> test for class B

class B
  remove_method :test
end

b.test
=> test for class A

class B
  undef_method :test
end

b.test
=> undefined method `test' for #<B:0xb7c9a754> (NoMethodError)

In my previous post, used undef_method instead of remove_method thinking
(without trying it) that remove_method would only remove it from the
singleton class. I tried it now, and I saw it works with both methods. It
seems singleton classes are treated in a different way.

Stefano

···

On Jan 10, 2008 6:12 PM, Stefano Crocco <stefano.crocco@alice.it> wrote:

Alle giovedì 10 gennaio 2008, botp ha scritto:

> > class << s1
> > undef_method :print
> > end
>
> ah, undef_,
>
> how does it compare then if i do,
> class << s1
> remove_method :print
> end
>
> i mean will undef_ do a remove or what?
>
> but anyway, that is cool Stefano. thanks for the new i've just learned.
>
> kind regards -botp

Well, in general remove_method will remove it only from the class where it's
called. If a superclass defines the same method, the superclass's method will
be called. According to ri, instead, undef_method, prevents the class from
responding to the method at all. Here's an example showing the difference

class A
  def test
    puts "test for class A"
  end
end

class B < A
  def test
    puts "test for class B"
  end
end

b = B.new
b.test
=> test for class B

class B
  remove_method :test
end

b.test
=> test for class A

class B
  undef_method :test
end

b.test
=> undefined method `test' for #<B:0xb7c9a754> (NoMethodError)

In my previous post, used undef_method instead of remove_method thinking
(without trying it) that remove_method would only remove it from the
singleton class. I tried it now, and I saw it works with both methods.

Does it? I cannot reproduce that behavior:

class << Class::new {
  def a; 42 end
}
  remove_method :a
end

singleton.rb:7:in `remove_method': method `a' not defined in Class (NameError)
        from singleton.rb:7

It
seems singleton classes are treated in a different way.

IIRC Mauricio Fernandez has shown that undef_method leaked (or still
leaks) so normally I would use remove_method
whenever possible, which is however not the case here.
Cheers
Robert

···

On Jan 10, 2008 11:54 AM, Stefano Crocco <stefano.crocco@alice.it> wrote:

> On Jan 10, 2008 6:12 PM, Stefano Crocco <stefano.crocco@alice.it> wrote:

--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Alle giovedì 10 gennaio 2008, Robert Dober ha scritto:

Does it? I cannot reproduce that behavior:

class << Class::new {
def a; 42 end
}
remove_method :a
end

singleton.rb:7:in `remove_method': method `a' not defined in Class
(NameError) from singleton.rb:7

You're right, it doesn't work. I didn't look close enough at the output.

Stefano