undef - Why would you want to undefine a method in ruby?

前端 未结 7 619
无人共我
无人共我 2020-12-15 09:41

I\'ve never seen undef - or any thing else that allows you to undefine a method - in any other programming languages. Why is it needed in Ruby?

EDIT: I\'m not arguin

相关标签:
7条回答
  • 2020-12-15 10:18

    There's also the blank class pattern in Ruby that needs the undef functionality.

    The idea is to strip every method from your new class so that every call you make to it ends in #method_missing. That way you can implement a real proxy that just shuffles everything through. Implementing the decorator pattern with this is around ten lines of code, no matter how big your target class is.

    If you want to see that idiom in action look at one of Ruby's mocking frameworks, they use it alot. Something like flexmock.

    Another example is when you add functions dynamicly onto a class based on some condition. In a game you might add an #attack method onto the player object and then take it away when he´s paralyzed instead of doing it with a boolean flag. That way the calling class can check for the availabty of the method and not the flag. I´m not saying that this is a good idea, just that it´s made possible and there are far smarter people then me coming up with useful stuff to do with this.

    0 讨论(0)
  • 2020-12-15 10:20

    I am consuming an external API, and one of the JSON responses contains a field named "methods". I'm creating an OpenStruct around the json, just to make the json more manageable. When calling openStruct.methods, it returns the result of Object instance method "methods".

    So I did:

    class MyOpenStruct < OpenStruct
       def methods
       end
    
       undef :methods
    end 
    
    openStruct = OpenStruct.new(my_json)
    
    0 讨论(0)
  • 2020-12-15 10:22

    If your using Single Table Inheritance with an ORM, such as ActiveRecord, you may want to undefine the methods for fields which are not being used for a particular class/object.

    # table: shapes, with columns: name, sides, radius, type
    class Shape < ActiveRecord::Base
    end
    
    class Circle < Shape
    end
    
    class Square < Shape
      undefine_method :radius
    end
    

    Note: This doesn't actually work in ActiveRecord as it internally expects a method for every field to always be defined.

    Note: A square does have a radius its just not commonly used, but you get the gist? Think of some property your storing in the database which a Circle has, but a Square does not.

    0 讨论(0)
  • 2020-12-15 10:23

    Defining methods, classes and objects at runtime is a very nice feature of Ruby. It allows you to extend classes (remember they are "open"). If you look at Rails, it has a #find method to find objects in a model but you can also use find_by_user; that method does not exist (so #method_missing is called) but gets created at run-time.

    If you want to create a Domain Specific Language or DSL, using #missing_method can be useful.

    0 讨论(0)
  • 2020-12-15 10:25

    You can look at all of Rails for examples of defining methods at runtime (aka metaprogramming). By calling one method in your class definition, it can define a whole bunch of methods for all instances of that class...

    0 讨论(0)
  • 2020-12-15 10:32

    I've seen this used in conjunction with Mixins; so you can include the whole thing and then undef the methods it shouldn't support.. e.g. the ruby graphics library shoes.

    The button class mixes in the clickable module, and then undef's the release method because buttons don't support it.

    Another quick example, so it's available here:

    module Walkable
      attr_accessor :location
      def walk(steps)
        @location += steps
      end
      def walk_back(steps)
        @location -= steps
      end
    end
    class Zombie
      include Walkable
      undef walk_back #zombies can only walk forwards
    end
    
    0 讨论(0)
提交回复
热议问题