新手问题 关于 eval 操作实例变量的问题

ailms · 2013年03月31日 · 最后由 ailms 回复于 2013年04月05日 · 2827 次阅读

来自 The Ruby programming 的 8.3.1  Querying, Setting, and Testing Variables

Note that eval evaluates its code in a temporary scope. eval can alter the value of instance variables that already exist. But any new instance variables it defines are local to the invocation of eval and cease to exist when it returns. (It is as if the evaluated code is run in the body of a block—variables local to a block do not exist outside the block.)

看这段话应该是新的实例变量在 eval 执行后会消失,但测试发现并没有 (@z变量)

[code] irb(main):001:0> class Point irb(main):002:1> def initialize(x,y) irb(main):003:2> @x,@y=x,y irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> p=Point.new(1,2) => # irb(main):007:0> irb(main):008:0* def get_bind irb(main):009:1> binding irb(main):010:1> end => nil irb(main):011:0> b=p.get_bind => #Binding:0x81915b0 irb(main):012:0> irb(main):013:0* eval("@x",b) => 1 irb(main):014:0> irb(main):015:0* eval("@x=10",b) => 10 irb(main):016:0> eval("@x",b)
=> 10 irb(main):017:0> irb(main):018:0* eval("@z=2",b) => 2 irb(main):019:0> eval("@z",b)
=> 2 irb(main):020:0> p.instance_variables => [:@x, :@y, :@z] irb(main):021:0> irb(main):022:0* irb(main):023:0* [/code]

怎么可能消失啊 那个可是 instance variable 啊

#1 楼 @iBachue

But any new instance variables it defines are local to the invocation of eval and cease to exist when it returns

#2 楼 @ailms 好吧 那我也不理解这句话什么意思

class Demo
  def initialize(n)
    @secret = n
  end
  def get_binding
    return binding()
  end
end

k1 = Demo.new(99)
b1 = k1.get_binding
k2 = Demo.new(-3)
b2 = k2.get_binding

eval("@secret", b1)   #=> 99
eval("@secret", b2)   #=> -3
eval("@secret")       #=> nil

@ailms 那段话应该是这个意思

#4 楼 @NonTwitter

应该不是,如果不指定任何 binding,当然返回 nil。这个跟是不是 local scope 应该无关

可能和 ruby 版本有关

#6 楼 @jjym

恩,我也是这么觉得。

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