From: Josh Cheek Date: 2011-04-18T08:11:31+09:00 Subject: Re: Undefine Method Only Marks the Method Undefined --0016e68e9a63ec62e904a12564a5 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Sun, Apr 17, 2011 at 5:37 PM, Su Zhang wrote: > Hello, > > According to the book Programming Ruby by Dave Thomas, "an > unde=EF=AC=81ned method still exists - it is simply marked as being unde= =EF=AC=81ned." > Why is it not completely removed? > > I find this somewhat related to the fact that an object still cannot be > dumped after "undefing" its singleton methods. > > obj =3D Object.new > > def obj.foo > end > > p obj.respond_to? :foo # =3D> true > > class << obj > undef foo > end > > p obj.respond_to? :foo # =3D> true > > Marshal.dump(obj) # =3D> error > > -- > Posted via http://www.ruby-forum.com/. > I assume because the intuition is that undefining a method on an object means the object should raise the undefined error when you try to call it. But simply removing it would not prevent Ruby from finding an inherited version of the method. ie o =3D Object.new o.to_s # =3D> "#" def o.to_s "o#to_s" end o.to_s # =3D> "o#to_s" class << o remove_method :to_s end o.to_s # =3D> "#" It still has a to_s method, because it inherits one from Object. What if yo= u want it to not respond to that one? You can't undefine the method on object= , or every object loses it's inherited to_s method. So you need to interrupt dispatch when this method is called. Hence undef simply raises the same error you would have gotten if it hadn't found the method: o =3D Object.new o.to_s # =3D> "#" def o.to_s "o#to_s" end o.to_s # =3D> "o#to_s" class << o undef :to_s end o.to_s # =3D> # ~> -:15:in `
': undefined method `to_s' for # (NoMethodError) --0016e68e9a63ec62e904a12564a5--