Undefine Method Only Marks the Method Undefined

Discussion in 'Ruby' started by Su Zhang, Apr 17, 2011.

  1. Su Zhang

    Su Zhang Guest

    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/.=
    Su Zhang, Apr 17, 2011
    #1
    1. Advertising

  2. 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 #=3D> 'foo'
    C.new.bar #=3D> 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 =3D Object.new
    def obj.foo
    end

    Marshal.dump(obj) #=3D> TypeError: singleton can't be dumped

    class << obj
    remove_method :foo
    end

    Marshal.dump(obj) #=3D> "\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

    http://carboni.ca/

    On Apr 17, 2011, at 6:37 PM, Su Zhang wrote:

    > Hello,
    >=20
    > 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?
    >=20
    > I find this somewhat related to the fact that an object still cannot =

    be
    > dumped after "undefing" its singleton methods.
    >=20
    > obj =3D Object.new
    >=20
    > def obj.foo
    > end
    >=20
    > p obj.respond_to? :foo # =3D> true
    >=20
    > class << obj
    > undef foo
    > end
    >=20
    > p obj.respond_to? :foo # =3D> true
    >=20
    > Marshal.dump(obj) # =3D> error
    >=20
    > --=20
    > Posted via http://www.ruby-forum.com/.
    Michael Edgar, Apr 18, 2011
    #2
    1. Advertising

  3. Su Zhang

    Josh Cheek Guest

    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> "#<Object:0x0000010086a460>"

    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> "#<Object:0x0000010086a460>"



    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> "#<Object:0x0000010086a488>"

    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 `<main>': undefined method `to_s' for
    #<Object:0x0000010086a488> (NoMethodError)
    Josh Cheek, Apr 18, 2011
    #3
  4. Su Zhang

    Su Zhang Guest

    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/.
    Su Zhang, Apr 18, 2011
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?UmljaA==?=
    Replies:
    15
    Views:
    8,052
    aparnalr
    Sep 14, 2011
  2. Rafal 'Raf256' Maj

    undefine all macros from a file

    Rafal 'Raf256' Maj, Jan 19, 2005, in forum: C++
    Replies:
    1
    Views:
    2,979
    Jonathan Turkanis
    Jan 19, 2005
  3. Alden Pierre
    Replies:
    7
    Views:
    389
  4. Pietro Cerutti

    undefine for functions

    Pietro Cerutti, Aug 30, 2007, in forum: C Programming
    Replies:
    8
    Views:
    369
    Eric Sosman
    Aug 31, 2007
  5. Scott Bass
    Replies:
    10
    Views:
    223
    Brian McCauley
    May 30, 2005
Loading...

Share This Page