Ruby 怎么动态地为类添加实例方法?

Alexander · 2012年04月08日 · 最后由 shulin 回复于 2013年12月12日 · 5103 次阅读

比如说有两个类 A 的实例 a1, a2:

a1 = A.new
a2 = A.new


此时要为 a1, a2 都添加一个方法 m, 该怎么办呢? 除了下面这两种方法:

class A
  def m
  end
end


A.class_eval do
  def m
  end
end

def a1.m
end

#1 楼 @hooopo 这样只能为 a1 新建一个单件方法。

a1.class.send(:define_method, :m) { puts self }

#3 楼 @xzgyb 这样其实和我的第二种方法是一样的,有没有不需要用到 eval 的方法

既然要为一个类的所有实例都添加方法,为什么不直接在类定义的时候加? 还是说为不同的实例添加的方法实现或名称都不同?

#5 楼 @willmouse 如果类不是自己定义的呢?

#6 楼 @Alexander 不论是不是自己定义的,打开类添个方法不就得了(猴子补丁),这就和你写的第一种方法一样。 还是怕和类中已存在的方法名冲突?

可以用 Module, 名字冲突建议用 alias chain

module AExt
  def m
  end
end

# for all A's instance
A.send :include AExt

# only for a1 and a2
a1.extend AExt
a2.extend AExt

#9 楼 @Alexander

a1.class.send(:define_method,:m){}

A.class_eval do
  def m
  end
end

这样就很优雅

12 楼 已删除
需要 登录 后方可回复, 如果你还没有账号请 注册新账号