【问题标题】:How to access a (shadowed) global function in ruby如何在 ruby​​ 中访问(阴影)全局函数
【发布时间】:2010-04-21 10:02:39
【问题描述】:

我想知道如何从一个还定义了方法fn 的类访问ruby 中的全局函数fn。我通过像这样对函数进行别名来解决问题:

定义 结尾 类酒吧 别名 global_fn fn 定义 # 如何在没有别名的情况下访问全局 fn global_fn 结尾 结尾

我正在寻找与 c++ 的 :: 类似的东西来访问全局范围,但我似乎无法找到有关它的任何信息。我想我不知道具体我在寻找什么。

【问题讨论】:

    标签: ruby scope


    【解决方案1】:

    在顶层,def 将私有方法添加到 Object

    我能想到三种获取顶层函数的方法:

    (1) 使用send 调用Object 本身的私有方法(仅当方法不是mutator 时才有效,因为Object 将成为接收者)

    Object.send(:fn)
    

    (2) 获取顶级方法的Method 实例并将其绑定到您要调用它的实例:

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

    (3) 使用super(假设Bar下面没有超类Object重新定义函数)

    class Bar
      def fn
        super
      end
    end
    

    更新:

    由于解决方案 (2) 是更可取的解决方案(在我看来),我们可以尝试通过在 Object 上定义一个名为 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
    

    像下面这样使用:

    class Bar
      def fn
        super_method Object, :fn
      end
    end
    

    super_method 的第一个参数必须是 Bar 的有效超类,第二个参数是您要调用的方法,所有剩余参数(如果有)作为参数传递给所选方法。

    【讨论】:

    • 我不知道全局方法实际上是添加到Object中的。这是否意味着如果 Bar 有一个也定义 fn 的超类,我的别名方法(如您的超级方法)也会中断?
    • @yngvedh,没错。它会以同样的方式破裂。 IMO 最通用的方法是使用第二种解决方案。
    • @banister,没有其他方法可以做到这一点吗?我在想一些语法上更令人愉悦的东西,比如 c++ 的 Object::fn。
    • @yngvedh,刚刚更新了Object 上的一个方法,希望可以为您改进语法
    • @yngvedh,我突然想到,“全局函数”永远不应该是一个突变方法,所以也许解决方案 (1) 最适合你。但是,在一般情况下......即调用在继承链中某处的任意基类上定义的方法,我认为super_method 方法是一个很好的方法;)
    猜你喜欢
    • 2010-10-11
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 2022-07-20
    • 2011-05-31
    相关资源
    最近更新 更多