首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何覆盖Kernel.load

如何覆盖Kernel.load
EN

Stack Overflow用户
提问于 2015-08-05 18:31:19
回答 1查看 834关注 0票数 9

我需要重写Kernel.load,以便监视和处理我们为监视而编写的一些Ruby文件。然而,这种诡计似乎是免疫的。

覆盖requirerequire_relative很容易,但是如果我没记错的话,load就位于它们下面,并限制了实际读取的文件。

下面是为什么它似乎受到保护而不被覆盖:

代码语言:javascript
复制
Kernel.module_eval do

  alias_method :original_require, :require
  def require(filename)
    require_result = original_require(filename)
    puts "required #{filename}"

    require_result
  end

  alias_method :original_load, :load
  def load(filename, wrap=true)
    load_result = original_load(filename, wrap)
    puts "loaded #{filename}"

    load_result
  end
end
include Kernel

require 'open-uri'
puts 'done'

运行该输出:

代码语言:javascript
复制
required uri/rfc2396_parser
required uri/rfc3986_parser
required uri/common
required uri/common
required uri/generic
required uri/generic
required uri/ftp
required uri/generic
required uri/http
required uri/http
required uri/https
required uri/generic
required uri/ldap
required uri/ldap
required uri/ldaps
required uri/generic
required uri/mailto
required uri
required stringio
required date_core
required date
required time
required open-uri
done

我满足于只覆盖requirerequire_relative。然而,我很好奇load是怎么回事。

后想:

看起来load不是由requirerequire_relative调用的。我认错了。抓得好哑光

这个问题类似于"如何在Ruby中重写require?“。

读得好:

约格氏评论

我还想给Module#prepend一些爱,这将允许您只使用Super而不是那些丑陋的alias_method东西,还有额外的好处,您的修改实际上会出现在祖先链中,因此更容易调试。

是非常明智和值得使用的。

  • http://ruby-doc.org/core-2.2.2/Module.html#method-i-prepend
  • 特性
  • 特性
EN

回答 1

Stack Overflow用户

发布于 2015-08-06 20:42:35

下面是两个简单的示例,它们似乎适用于覆盖requirerequire_relative,它们基于"当猴子修补一个方法时,你能从新的实现中调用重写的方法吗?“中的示例。

代码语言:javascript
复制
module Kernel
  old_require = method(:require)
  define_method(:require) do |filename|
    puts "require #{filename}"
    old_require.call(filename)
  end

  old_require_relative = method(:require_relative)
  define_method(:require_relative) do |filename|
    puts "require_relative #{filename}"
    old_require_relative.call(filename)
  end
end

代码语言:javascript
复制
module KernelExtensions
  def require(filename)
    puts "require #{filename}"
    super
  end
  def require_relative(filename)
    puts "require_relative #{filename}"
    super
  end
end

class Object
  prepend KernelExtensions
end

运行第二个使用

代码语言:javascript
复制
module Kernel
  prepend KernelExtensions
end

没有工作,但由于Object包含内核,使用class Object覆盖似乎工作得很干净。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31840181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档