分享 Ruby 基础篇之如何山寨 require 和 load

poshboytl · 2013年04月27日 · 最后由 zputee 回复于 2013年04月30日 · 4099 次阅读

通过山寨 require 和 load 方法来解释它们的区别和联系

我就直接贴链接啦:

http://terrytai.com/articles/shaizhai-require-load

Hope you will like it :)

推上看过,特来顶下!

转推了。

这思路,膜拜一下

转过推 再来顶一下

先点个喜欢,再看……

看到最后,会心一笑

看楼主提供的山寨版的 load, 给我一个错觉,就是楼主认为 eval 和 load 是等价的。所以用 eval 来实现 load. (虽然真实的 load 貌似是 C 实现的), 我想问一个问题,在你写山寨版 load 时,你有考虑过 load 和 eval 的区别吗?

看代码:

module Kernel
  def load1(fn)
    eval File.read(fn)
  end
end

load1 './person.rb'

p Person   # => Kernel::Person

而如果用常规的 load.


module Kernel
  def load1(fn)
    load fn
  end
end

load1 './person.rb'

p Person   # => Person.

因为 Person.rb 一个臆造的文件,而你仅仅使用一个 puts 输出来验证 load 是否正确,肯定不妥。(不管在那个上下文空间被执行,都会 puts), 而如果需要确保第一个 load1 工作的像 load 那样,也只有定义在 Object 中,作为一个私有方法,才有可能正确。

好吧,如果我说这些有些多余 (楼主根本没这么想), 就当我上面废话好了。

10 楼 已删除

#9 楼 @zw963 哈哈,你说的没错。

我的实现和 c 语言版并不是完全等同的。

所以我叫他山寨,而并不是要写一个 load 方法的 ruby 实现... 所以我并没有先定义出 load 的 spce 是什么,写测试,再让它 pass。如你所说我甚至都没有在 module Kernel 中定义方法,而就在当前文件做了定义。

这个地方只是为了讲解啦 :)

感谢你如此严谨和细心... 哈哈哈哈哈~~ 不错....

#9 楼 @zw963 @poshboytl
刚好我写了篇:关于类名常量,想过这个问题。http://ruby-china.org/topics/10608 打开 Object 类即可做到一致了。

#打开Object类,Object mixin Kernel,所以可以覆盖kernel中的方法
class Object  
  def load1(fn)
    eval File.read(fn)
  end
end
load1 './person.rb'
p Person   # => Person.

如果要原生 load 一样,放入 Kernel,可以使用 class_eval。

module Kernel
  def load3(fn)
    Object.class_eval %{                       
      eval File.read(fn)
    }
  end
end

load3 './person.rb'
p Person
#=>Person

self.class.method(:load3)
#=>#<Method: Class(Kernel)#load3>
self.class.method(:load)
#=>#<Method: Class(Kernel)#load>
需要 登录 后方可回复, 如果你还没有账号请 注册新账号