How to access a (shadowed) global function in ruby

后端 未结 1 1956
一向
一向 2020-12-14 20:20

I was wondering how to access a global function fn in ruby from a class which also defined a method fn. I have made a workaround by aliasing the fu

相关标签:
1条回答
  • 2020-12-14 20:54

    At the top-level a def adds a private method to Object.

    I can think of three ways to get the top-level function:

    (1) Use send to invoke the private method on Object itself (only works if the method is not a mutator since Object will be the receiver)

    Object.send(:fn)
    

    (2) Get a Method instance of the top-level method and bind it to the instance you want to invoke it on:

    class Bar
      def fn
        Object.instance_method(:fn).bind(self).call
      end
    end
    

    (3) Use super (assumes no super classes of Bar below Object redefine the function)

    class Bar
      def fn
        super
      end
    end
    

    UPDATE:

    Since solution (2) is the preferable one (in my opinion) we can try to improve the syntax by defining a utility method on Object called super_method:

    class Object
      def super_method(base, meth, *args, &block)
        if !self.kind_of?(base) 
          raise ArgumentError, "#{base} is not a superclass of #{self}" 
        end
    
        base.instance_method(meth).bind(self).call(*args, &block)
      end
    end
    

    Use like the following:

    class Bar
      def fn
        super_method Object, :fn
      end
    end
    

    Where the first argument to super_method must be a valid superclass of Bar, the second argument the method you want to invoke, and all remaining arguments (if any) are passed along as parameters to the selected method.

    0 讨论(0)
提交回复
热议问题