Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #3071 > unrolled thread
| Started by | Su Zhang <zhangsu@live.com> |
|---|---|
| First post | 2011-04-17 17:37 -0500 |
| Last post | 2011-04-17 19:11 -0500 |
| Articles | 4 — 3 participants |
Back to article view | Back to comp.lang.ruby
Undefine Method Only Marks the Method Undefined Su Zhang <zhangsu@live.com> - 2011-04-17 17:37 -0500
Re: Undefine Method Only Marks the Method Undefined Michael Edgar <adgar@carboni.ca> - 2011-04-17 18:11 -0500
Re: Undefine Method Only Marks the Method Undefined Josh Cheek <josh.cheek@gmail.com> - 2011-04-17 18:11 -0500
Re: Undefine Method Only Marks the Method Undefined Su Zhang <zhangsu@live.com> - 2011-04-17 19:11 -0500
| From | Su Zhang <zhangsu@live.com> |
|---|---|
| Date | 2011-04-17 17:37 -0500 |
| Subject | Undefine Method Only Marks the Method Undefined |
| Message-ID | <c362ab059556406ae9960b3915006349@ruby-forum.com> |
Hello, According to the book Programming Ruby by Dave Thomas, "an undefined method still exists - it is simply marked as being undefined." 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 = Object.new def obj.foo end p obj.respond_to? :foo # => true class << obj undef foo end p obj.respond_to? :foo # => true Marshal.dump(obj) # => error -- Posted via http://www.ruby-forum.com/.
[toc] | [next] | [standalone]
| From | Michael Edgar <adgar@carboni.ca> |
|---|---|
| Date | 2011-04-17 18:11 -0500 |
| Message-ID | <D5A46153-3A5D-40CD-B832-D73F875BF0FE@carboni.ca> |
| In reply to | #3071 |
Hi Su, The difference between undef_method and remove_method is, as you point out, that undef_method marks the method as undefined. This difference is most simply demonstrated with inheritance: if method dispatch reaches an undefined method, it stops looking for the method and gives an error. However, remove_method eliminates the method entirely, and the next ancestor will then be considered. In code: class A def foo; 'foo'; end def bar; 'bar'; end end class B < A def foo; 'B foo'; end def bar; 'B bar'; end remove_method :foo undef_method :bar end class C < B end C.new.foo #=> 'foo' C.new.bar #=> NoMethodError: undefined method `bar' for #<C:0x0000010161f7e0> Regarding Marshal.dump, If you use remove_method instead of undef_method, you will in fact be able to dump the object again: obj = Object.new def obj.foo end Marshal.dump(obj) #=> TypeError: singleton can't be dumped class << obj remove_method :foo end Marshal.dump(obj) #=> "\x04\bo:\vObject\x00" The (simplified) technical reason why undef_method doesn't work and remove_method does, regarding Marshal.dump, is that undef_method leaves the undefined flag as additional state in the singleton class, whereas remove_method will leave `obj` with an empty singleton class, identical to Object. Hope this helps, Michael Edgar adgar@carboni.ca http://carboni.ca/ On Apr 17, 2011, at 6:37 PM, Su Zhang wrote: > Hello, > > According to the book Programming Ruby by Dave Thomas, "an > undefined method still exists - it is simply marked as being undefined." > 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 = Object.new > > def obj.foo > end > > p obj.respond_to? :foo # => true > > class << obj > undef foo > end > > p obj.respond_to? :foo # => true > > Marshal.dump(obj) # => error > > -- > Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-04-17 18:11 -0500 |
| Message-ID | <BANLkTima8ViGruC+NS9kF1NNti_QvJT8Jw@mail.gmail.com> |
| In reply to | #3071 |
On Sun, Apr 17, 2011 at 5:37 PM, Su Zhang <zhangsu@live.com> wrote: > Hello, > > According to the book Programming Ruby by Dave Thomas, "an > undefined method still exists - it is simply marked as being undefined." > 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 = Object.new > > def obj.foo > end > > p obj.respond_to? :foo # => true > > class << obj > undef foo > end > > p obj.respond_to? :foo # => true > > Marshal.dump(obj) # => 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 = Object.new o.to_s # => "#<Object:0x0000010086a460>" def o.to_s "o#to_s" end o.to_s # => "o#to_s" class << o remove_method :to_s end o.to_s # => "#<Object:0x0000010086a460>" It still has a to_s method, because it inherits one from Object. What if you 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 = Object.new o.to_s # => "#<Object:0x0000010086a488>" def o.to_s "o#to_s" end o.to_s # => "o#to_s" class << o undef :to_s end o.to_s # => # ~> -:15:in `<main>': undefined method `to_s' for #<Object:0x0000010086a488> (NoMethodError)
[toc] | [prev] | [next] | [standalone]
| From | Su Zhang <zhangsu@live.com> |
|---|---|
| Date | 2011-04-17 19:11 -0500 |
| Message-ID | <f38daecadd3fc60a00d0b91932d887e9@ruby-forum.com> |
| In reply to | #3071 |
Thank you - Michael and Josh, now this makes perfect sense to me. It's funny how I wasn't aware of the existence of `remove_method' at all! -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.ruby
csiph-web