锁定老帖子 主题:一个有趣的问题: 如何获取引用名?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-24
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的名字, 那么问题就解决了. 那么, get_ref_name 存在么? 该如何实现? (注: 不要告诉我用a,b = b,a来实现变量交换, 这个不是要讨论的问题) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-07-24
我的一个实现,比较丑陋,通过查找local_variables
a=100 b=200 class Test attr_accessor :name end def get_ref_name(x,vars,b) vars.each do |var| begin return var if eval("#{var}",b)==x and var!='x' rescue end end end c=Test.new puts get_ref_name(a,local_variables,binding) puts get_ref_name(c,local_variables,binding)
|
|
返回顶楼 | |
发表时间:2008-07-24
在ruby层面只能用local_variables来实现了
|
|
返回顶楼 | |
发表时间:2008-07-25
dennis_zane 写道
我的一个实现,比较丑陋,通过查找local_variables
a=100 b=200 class Test attr_accessor :name end def get_ref_name(x,vars,b) vars.each do |var| begin return var if eval("#{var}", b) == x and var!='x' rescue end end end c=Test.new puts get_ref_name(a,local_variables,binding) puts get_ref_name(c,local_variables,binding)
用local_variables还是有很大局限性, 例如: a = 100 b = 200 c = a 这时 eval("#{var}", b) == x 这句对局部变量a和c都成立, 因为'=='操作符比较的是值.
另外,还要挖空心思去给'x'取个特别的名字,要不然 var != 'x' 也很容易被击中.
很遗憾的是Kernel#caller没有提供参数列表信息,否则这个问题就好解决了.
|
|
返回顶楼 | |
发表时间:2008-07-25
我实在想不出获取变量名的实际用途是什么?
如果是为了类似指针方式获取值,ruby有提供ObjectSpace._id2ref |
|
返回顶楼 | |
发表时间:2008-07-25
Quake Wang 写道 我实在想不出获取变量名的实际用途是什么?
如果是为了类似指针方式获取值,ruby有提供ObjectSpace._id2ref 要说到用处么, 有了它就可以实现类似'宏'的功能, 也有可能对有些meta trick有用处吧. 顺便也看看ruby对代码自省到什么程度, 呵呵~ |
|
返回顶楼 | |
发表时间:2008-07-25
use powser of ParseTree?
need to wrap magic code in a method or block. maybe you guys heard it long time ago, while I guess ParseTree will be the next big thing for ruby. |
|
返回顶楼 | |
发表时间:2008-07-25
a = 100
get_ref_name(a) 传递的是指向100的引用,跟a一点关系都没有, 怎么可能取到a呢。 除了判断值相等,没法判断传的是什么。 如果判断值相等,返回的也只能是数组。 真想知道问GC吧。 |
|
返回顶楼 | |
发表时间:2008-07-28
>(注: 不要告诉我用a,b = b,a来实现变量交换, 这个不是要讨论的问题) 不好意思,a,b = b,a同你的实现有何不同,望赐教 |
|
返回顶楼 | |
发表时间:2008-07-29
有的时候,代码是逻辑,有的时候代码是复制,其实最后代码编写应该是哲学与美学。我们的日本工程师就是这方面的天才
|
|
返回顶楼 | |