新手问题 关于 Proc 的一点疑问

wazhxi · 2016年03月11日 · 最后由 wazhxi 回复于 2016年03月12日 · 1922 次阅读

新手..问题描述很乱..

class Class
  def set_class_method(sym,&block)
    obj = self.allocate
    self.send(:define_method,sym,block)
  end
end
A = Class.new
a = A.new
b = A.new
A.set_class_method(:m){@s = 2}#检查{@s = 2}的时候发现是Proc类型

a.instance_variable_get(:@s)#nil
b.instance_variable_get(:@s)#nil
a.m
a.instance_variable_get(:@s)#2
b.instance_variable_get(:@s)#nil

A.set_class_method(:m){@s = 3}
A.set_class_method(:m,&b.method(:m).to_proc)#传入的还是Proc类型
a.m
a.instance_variable_get(:@s)#2,没有变化
b.instance_variable_get(:@s)#3

第一个 proc 似乎没有指定 self,第二个的 self 是 b 有没有什么办法可以让第二个 proc 像第一个一样,不指定 self

这个涉及到名字绑定,如果你可以更改 set_class_method 的签名的话,直接传入 UnboundMethod 就可以咯,示例代码:

class Class
  # block 可以是 Proc, Method, UnboundMethod, etc.
  def set_class_method(sym, block)
    self.send(:define_method,sym,block)
  end
end


A = Class.new
a = A.new
b = A.new


A.set_class_method(:m,Proc.new{@s = 2})#传入未 bind 的 Proc 对象
p a.instance_variable_get(:@s)#nil
p b.instance_variable_get(:@s)#nil
a.m
p a.instance_variable_get(:@s)#2
p b.instance_variable_get(:@s)#nil


print "\n"
a.instance_variable_set(:@s, nil)
b.instance_variable_set(:@s, nil)
print "\n"


A.set_class_method(:m,Proc.new{@s = 3})
A.set_class_method(:m,b.method(:m).to_proc)# 传入已 bind 的 Proc 对象
p a.instance_variable_get(:@s)#nil
p b.instance_variable_get(:@s)#nil
a.m
p a.instance_variable_get(:@s)#nil
p b.instance_variable_get(:@s)#3


print "\n"
a.instance_variable_set(:@s, nil)
b.instance_variable_set(:@s, nil)
print "\n"


A.set_class_method(:m,Proc.new{@s = 4})
A.set_class_method(:m,b.method(:m).unbind)# 传入 UnboundMethod
p a.instance_variable_get(:@s)#nil
p b.instance_variable_get(:@s)#nil
a.m
p a.instance_variable_get(:@s)#4
p b.instance_variable_get(:@s)#nil

楼上正解。 我只是想说,这样的代码,以后真的能维护的下去么

#2 楼 @SmileZero 不用在意维护..真要写的话我也不会写成这样..

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