我们知道, 对于
这样的一条语句, a是一个指向 "100" 这个对象的引用. 那么, 如何根据a得到它的名字"a"或者符号:a ?
我现在实现了一个'swap'函数,它的作用是交换两个变量的值, 由于Ruby没有类似C的'指针',所以这个swap实现起来还真有点麻烦:
好了, 这个swap有两个缺陷:
1) 为了获取caller's binding, 需要带一个空的闭包. 不过这个问题好解决, rails中有Binding.of_caller的实现,用它就可以省去那个空闭包.
2) 为了获取待交换的变量名, 传入swap的参数不能是a,b本身,而需要对应的symbol或string, 看起来有点别扭. 如果存在一个函数get_ref_name(x)返回x的名字, 那么问题就解决了.
[b]那么, get_ref_name 存在么? 该如何实现?[/b]
(注: 不要告诉我用a,b = b,a来实现变量交换, 这个不是要讨论的问题)
a = 100这样的一条语句, a是一个指向 "100" 这个对象的引用. 那么, 如何根据a得到它的名字"a"或者符号:a ?
我现在实现了一个'swap'函数,它的作用是交换两个变量的值, 由于Ruby没有类似C的'指针',所以这个swap实现起来还真有点麻烦:
a = 100
b = 200
def swap(x, y, &block)
bind = block.binding
vx = eval("lambda { #{x} }", bind).call
vy = eval("lambda { #{y} }", bind).call
eval("lambda {|v| #{y.to_s} = v }", bind).call(vx)
eval("lambda {|v| #{x.to_s} = v }", bind).call(vy)
end
puts "a = #{a}, b = #{b}"
swap(:a, :b){}
puts "a = #{a}, b = #{b}"
好了, 这个swap有两个缺陷:
1) 为了获取caller's binding, 需要带一个空的闭包. 不过这个问题好解决, rails中有Binding.of_caller的实现,用它就可以省去那个空闭包.
2) 为了获取待交换的变量名, 传入swap的参数不能是a,b本身,而需要对应的symbol或string, 看起来有点别扭. 如果存在一个函数get_ref_name(x)返回x的名字, 那么问题就解决了.
[b]那么, get_ref_name 存在么? 该如何实现?[/b]
(注: 不要告诉我用a,b = b,a来实现变量交换, 这个不是要讨论的问题)
本文探讨了在Ruby中实现变量值交换的方法。作者通过定义一个'swap'函数实现了这一目标,并讨论了该函数存在的两个主要问题:一是需要传递空闭包以获取调用者的绑定;二是需要传递变量的符号而非变量本身。最后提出了理想情况下的解决方案。
70

被折叠的 条评论
为什么被折叠?



