Ruby为何在def与define_method中对变量的处理方式不同?
为什么Ruby中
def和define_method对局部变量的处理有差异? 这个问题的核心在于Ruby里两种方法定义方式的作用域规则完全不同,咱们结合你的代码拆解清楚:
1. def foo的行为解析
用def关键字定义实例方法时,它会创建一个独立的方法作用域,这个作用域和类定义阶段的局部变量作用域是完全割裂的。
你的代码里,类定义时的y = 2是类作用域的局部变量,但foo方法内部的y ||= 0,这里的y是方法内部新生成的局部变量——因为方法作用域找不到外部的y,所以会把它初始化为0,最终输出0。
你可以在foo里加一行p local_variables验证,会输出[:y],这个y只存在于foo方法内部。
2. define_method :bar的行为解析
define_method是通过**块(Block)**来定义方法的,而Ruby的块是闭包(Closure)——它会“记住”自己被定义时所在的作用域环境,能捕获这个作用域里的局部变量。
你的代码里,块是写在类定义的作用域中的,所以它会捕获到类作用域里的y = 2。当执行y ||= 0时,因为捕获到的y已经是2(非nil也非false),所以不会执行赋值操作,直接输出2。
同样可以验证:在块里加p local_variables,输出的[:y]就是类作用域里的那个变量。
一句话总结
def定义的方法有独立作用域,无法访问类定义阶段的局部变量define_method通过闭包块定义方法,能捕获并使用定义时所在作用域的局部变量
内容的提问来源于stack exchange,提问作者user899119
相关产品推荐
相关产品推荐

