【Ruby】instance_eval和class_eval用法讲解

最近开始学习Ruby,在看到instance_eval和class_eval的用法时,觉得很是困惑,于是对此进行研究并整理一下。

首先,我们先定义一个Test类,该类包含一个类方法print_class_var和一个实例方法print_var。在print_class_var中,我们定义了一个属于Test类的实例变量var,而在print_var中,我们定义了一个属于Test类实例的实例变量var,这两个var是不一样的。然后我们创建Test类的一个实例test,然后并分别对Test类和test实例使用instance_eval和class_eval。

class Test
  def self.print_class_var
    puts @var
  end

  def print_var
    puts @var
  end
end

test = Test.new

Test.instance_eval do
  def method1
    @var = 1
    puts "Class method"
  end
end

test.instance_eval do
  def method2
    @var = 2 
    puts "Eigenclass method"
  end
end

Test.class_eval do
  def method3
    @var = 3
    puts "Instance method"
  end
end

首先,我们对Test.instance_eval进行测试,分别调用Test.method1和test.method1。

 

Test.method1  #Class method
Test.print_class_var #1
test.print_var #

test.method1  #undefined method `method1' for #<Test:0x007fc5db945bd0> (NoMethodError)

可以看出,Test.method1能正常输出,而test.method1无法运行,并且在Test.method1执行之后,Test.print_class_var有输出结果,test.print_var没有输出结果,即Test.method1对Test类的实例变量进行了设置。

然后,我们对test.instance_eval进行测试,分别调用Test.method2和test.method2。

Test.method2  #undefined method `method2' for Test:Class (NoMethodError)

test.method2  #Eigenclass method
Test.print_class_var #
test.print_var #2

可以看出,Test.method2无法运行,而test.method2能正常输出,并且在test.method2执行之后,Test.print_class_var没有输出结果,test.print_var有输出结果,即test.method2对test的实例变量进行了设置。

最后,我们对Test.class_eval进行测试,分别调用Test.method3和test.method3。

Test.method3  #undefined method `method3' for Test:Class (NoMethodError)

test.method3  #Instance method
Test.print_class_var #
test.print_var #3

可以看出,Test.method3无法运行,而test.method3能正常输出,并且在Test.method3执行之后,Test.print_class_var没有输出结果,test.print_var有输出结果,即test.method3对test的实例变量进行了设置。

在做完上面3个测试之后,相信大家都很困惑,到底instance_eval和class_eval有什么区别呢?按照字面上的理解,instance_eval应该是用来创建实例方法,而class_eval应该是用来创建类方法。

但实际上,结果恰恰相反,instance_eval必须由instance来调用,可以用来定义单例方法(Eigenclass Method或者Singleton Method);而class_eval必须由class来调用,可以用来定义实例方法(Instance Method)。


对于Test.instance_eval的测试,由于Test类是Class类的一个实例,因此就定义了Test类的单例方法method1,而类方法属于单例方法,进而method1只会对Test类的实例变量进行操作。

对于test.instance_eval的测试,由于test是Test类的一个实例,因此就定义了test实例的单例方法method2,进而只会对test的实例变量进行操作。

对于Test.class_eval的测试,由于定义了Test类的实例方法method3,因此只会对test的实例变量进行操作。



转载请注明出处: http://blog.csdn.net/sunset108/article/details/48136571



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值