论坛首页 编程语言技术论坛

一个有趣的问题: 如何获取引用名?

浏览 6311 次
精华帖 (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来实现变量交换, 这个不是要讨论的问题)





   发表时间: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)
 

 

1 请登录后投票
   发表时间:2008-07-24  
在ruby层面只能用local_variables来实现了
1 请登录后投票
   发表时间: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没有提供参数列表信息,否则这个问题就好解决了.

 

0 请登录后投票
   发表时间:2008-07-25  
我实在想不出获取变量名的实际用途是什么?
如果是为了类似指针方式获取值,ruby有提供ObjectSpace._id2ref
0 请登录后投票
   发表时间:2008-07-25  
Quake Wang 写道
我实在想不出获取变量名的实际用途是什么?
如果是为了类似指针方式获取值,ruby有提供ObjectSpace._id2ref


要说到用处么, 有了它就可以实现类似'宏'的功能, 也有可能对有些meta trick有用处吧. 顺便也看看ruby对代码自省到什么程度, 呵呵~
0 请登录后投票
   发表时间: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.




0 请登录后投票
   发表时间:2008-07-25  
a = 100
get_ref_name(a)
传递的是指向100的引用,跟a一点关系都没有,
怎么可能取到a呢。

除了判断值相等,没法判断传的是什么。
如果判断值相等,返回的也只能是数组。
真想知道问GC吧。
0 请登录后投票
   发表时间:2008-07-28  

>(注: 不要告诉我用a,b = b,a来实现变量交换, 这个不是要讨论的问题)

不好意思,a,b = b,a同你的实现有何不同,望赐教
0 请登录后投票
   发表时间:2008-07-29  
有的时候,代码是逻辑,有的时候代码是复制,其实最后代码编写应该是哲学与美学。我们的日本工程师就是这方面的天才
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics