How to override Kernel.load

I need to override Kernel.load to watch and process some of the Ruby files we wrote for monitoring. However, he seems immune to such fraud.

It is easy to override require and require_relative , but load sits beneath them and the bottlenecks that the actual file is viewing, if I remember correctly.

That's why it seems to be protected from overriding:

 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' 

The execution of these outputs:

 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 

I only like to override require and require_relative . However, I'm curious what happens to load .


belated thoughts:

It looks like load not being called by require or require_relative . My fault. Good catch Matt .

This question is similar to " How to override a requirement in Ruby? ".

Good reading:

comment by JΓΆrg

I also want to get a little involved in the # prepend module, which will allow you to simply use the super, and not that ugly alias_method material, with the added bonus that your modifications will really appear in the family tree and therefore are much easier to debug.

very reasonable and noteworthy.

+7
ruby
source share
1 answer

Here are two simple examples that seem to work to override require and require_relative based on the examples in " When does the monkey fix the method, can you call the overridden method from the new implementation? "

 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 

or

 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 

Launch the second using

 module Kernel prepend KernelExtensions end 

doesn't work, but since the object includes the kernel, using class Object overrides seems to work cleanly.

0
source share

All Articles