How do I call a method that is a hash value?

前端 未结 7 792
后悔当初
后悔当初 2021-01-07 02:47

Previously, I asked about a clever way to execute a method on a given condition \"Ruby a clever way to execute a function on a condition.\"

The solutions and respons

7条回答
  •  无人及你
    2021-01-07 03:21

    If you really just want to pretty this sort of thing up, why not wrap all your methods in a class like so:

    # a container to store all your methods you want to use a hash to access
    class MethodHash
      alias [] send
      def one
        puts "I'm one"
      end
      def two
        puts "I'm two"
      end
    end
    
    x = MethodHash.new
    x[:one] # prints "I'm one"
    x.two # prints "I'm one"
    

    or, to use your example:

    # a general purpose object that transforms a hash into calls on methods of some given object
    class DelegateHash
      def initialize(target, method_hash)
        @target = target
        @method_hash = method_hash.dup
      end
      def [](k)
        @target.send(@method_hash[k])
      end
    end
    
    class A
      def initialize
        @a = DelegateHash.new(self, { 0 => :a })
      end
      def a()
        puts "hello world"
      end
      def b()
        @a[0]
      end
    end
    
    x = A.new
    x.a #=> prints "hello world"
    x.b #=> prints "hello world"
    

    One other basic error that you made is that you initialized @a outside of any instance method - just bare inside of the definition of A. This is a big time no-no, because it just doesn't work. Remember, in ruby, everything is an object, including classes, and the @ prefix means the instance variable of whatever object is currently self. Inside an instance method definitions, self is an instance of the class. But outside of that, just inside the class definition, self is the class object - so you defined an instance variable named @a for the class object A, which none of the instances of A can get to directly.

    Ruby does have a reason for this behaviour (class instance variables can be really handy if you know what you're doing), but this is a more advanced technique.

    In short, only initialize instance variables in the initialize method.

提交回复
热议问题