Ruby中的绑定和eval

ruby是一种脚本语言,他的每一步执行都需要一个上下文环境,我们知道ruby的顶层环境就是main作为self,ruby的eval可以把传入的字符串当作脚本代码来解释执行,这里同样需要一个作用域。我们来看一个实验:
irb
name = “tony”
eval(“p name”)
=> tony
def test
name = “hello”
end
test
=> hello
name
=> tony
这里说明方法里和方法外各自的作用域不同,并且方法内的局部变量不会覆盖外面的变量
我们再来看
def test_x
name = “ruby”
return binding
end
b = test_x
=><Binding:xxxxxxx>
eval(“name”,b)
=>ruby
好了,这里我们看到eval输出的是ruby而不是tony,那么说明eval的执行上下文环境是可以通过第二个参数传进去的,而此时,我们对方法进行了绑定,因此在这个作用域里,name就是ruby,那么我们接下来再去看看Binging到底绑定的是什么
irb打开一个新的会话窗口
class MyClass
         def test_bind
               name = ‘tony’
               @name = ‘Tony’
               b = binding
               age = 23
               @age = 24
               return b
         end
end
m = MyClass.new
b = m.test_bind
eval(‘m.name’)
=>undefined method ‘name’ for <MyClass:0xxxxxxx…>
说明在退出m的test_bind作用域后,我们无法访问其中的局部变量
eval(‘m.@name’)
=> syntax error,因为我们不能直接访问m.@name
eval(‘name’,b)
=>tony
说明,这个绑定包含定义绑定前的局部变量
eval(‘age’,b)
=>23
说明,这个绑定包含定义在绑定后的局部变量
eval(‘@name’,b)
=>Tony
说明,同样能绑定实例变量
eval(‘self’,b)
=><MyClass:0xxxxxxxx…>
说明绑定保存了当时的self对象
eval(‘self.name’,b)
undefined method ‘name’ of <MyClass:0xxxxxxxxxxxx>
综上:Binding用在方法中时,不论定义在哪里,它都能够保存当前作用域(方法)和当前的self对象,以供eval方法调用,同样地,在类方法也有同样的作用
接下来,我们再来看下Binding对proc等的保存
irb开启一个新的会话窗口
def test_bind(x,y,&p)
p “x:#{x},y:#{y}”
p p.call x,y
return binding
end
p1 = Proc.new(){|x,y| x+y}
p2 = Proc.new(){|x,y| x*y}
b1 = test_bind(3,5,&p1)
=>x:3,y:5
=>8
=><Binding:0xxxxxxxxx…>
b2 = test_bind(3,5,&p2)
=>x:3,y:5
=>15
=><Binding:-xxxxxxxxx>
eval(‘p.call x,y’,b1)
=>8
eval(‘p.call x,y’,b2)
=>15
充分说明,Binding不仅可以保存作用域的变量和self,还能保存作用域中的block对象
只有充分理解了ruby中的Binding,才能理解很多后面的东西,也才能更好地发挥eval的作用,就先记到这里!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值