instance_eval 与 class_eval 的区别

by 小赓赓。 at about 9 years ago, last updated at about 9 years ago
W

instance_eval

首先要明白instance_eval是所有类的实例方法,打开的是当前实例作用域。所以

class A
end

a = A.new
a.instance_eval do 
  def hello
    '343'
  end
end

puts a.hello
#=>343

其次因为class类本身也是Class类的一个实例,所以instance其实也可以用在类上,所以也可以定义类方法

class A
end

A.instance_eval do 
  def class_method
    '343'
  end
end

puts A.class_method
#=>343

class_eval

首先class_eval是只有类才能调用的,class_eval会重新打开当前类作用域.

class A
end


A.class_eval do 
  def instance_methods
    puts '343'
  end
  def self.hi
    puts 'hi'
    puts self
  end
end

a = A.new
puts a.instance_methods
puts A.hi
#=>343
#=>hi
#=>A

可以看出在一个类上调用了class_eval,就可以在其中定义该类的实例方法。

所以

  • instance_eval必须由实例调用,可以用来定义单例方法
  • class_eval必须由类调用,可以用来定义实例方法