[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

how to remove a method from an object ?

Valerio Schiavoni

1/10/2008 8:33:00 AM

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
8 Answers

Brian.LeRoux

1/10/2008 9:18:00 AM

0

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

botp

1/10/2008 9:58:00 AM

0

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 ?

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..
:)

kind regards -botp

Stefano Crocco

1/10/2008 10:12:00 AM

0

Alle gioved=EC 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 =3D Server.new
> s1.print #this work
>
> #now remove print from s1 somehow..
>
> s1.print #this should hit method_missing
>
> s2 =3D 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 =3D Server.new
s1.print

class << s1
undef_method :print
end

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

=3D>
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 t=
he=20
method from the singleton class of s1, only the call to s2.print works; the=
=20
call to s1.print raises a NoMethodError exception.

I hope this helps

Stefano

botp

1/10/2008 10:35:00 AM

0

On Jan 10, 2008 6:12 PM, Stefano Crocco <stefano.crocco@alice.it> wrote:
> 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

Stefano Crocco

1/10/2008 10:54:00 AM

0

Alle gioved=EC 10 gennaio 2008, botp ha scritto:
> On Jan 10, 2008 6:12 PM, Stefano Crocco <stefano.crocco@alice.it> wrote:
> > 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=20
called. If a superclass defines the same method, the superclass's method wi=
ll=20
be called. According to ri, instead, undef_method, prevents the class from=
=20
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 =3D B.new
b.test
=3D> test for class B

class B
remove_method :test
end

b.test
=3D> test for class A

class B
undef_method :test
end

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

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

Stefano

Robert Dober

1/10/2008 11:18:00 AM

0

On Jan 10, 2008 11:54 AM, Stefano Crocco <stefano.crocco@alice.it> wrote:
> Alle gioved=EC 10 gennaio 2008, botp ha scritto:
>
> > On Jan 10, 2008 6:12 PM, Stefano Crocco <stefano.crocco@alice.it> wrote=
:
> > > 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 i=
t'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 fro=
m
> 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 =3D B.new
> b.test
> =3D> test for class B
>
> class B
> remove_method :test
> end
>
> b.test
> =3D> test for class A
>
> class B
> undef_method :test
> end
>
> b.test
> =3D> 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 (NameErr=
or)
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


--=20
http://ruby-smalltalk.blo...

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

mockturtle

1/10/2008 12:51:00 PM

0



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
>
>
>
>
> 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

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

Stefano Crocco

1/10/2008 2:11:00 PM

0

Alle gioved=EC 10 gennaio 2008, Robert Dober ha scritto:
> Does it? I cannot reproduce that behavior:
>
> class << Class::new {
> =A0 def a; 42 end
> }
> =A0 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