`
rubynroll
  • 浏览: 205113 次
  • 性别: Icon_minigender_1
  • 来自: Wgt
社区版块
存档分类
最新评论

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

阅读更多
我们知道, 对于
 
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来实现变量交换, 这个不是要讨论的问题)





分享到:
评论
10 楼 rubynroll 2008-08-05  
baryon 写道

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

不好意思,a,b = b,a同你的实现有何不同,望赐教



如果把swap看作是'宏', 那么a,b = b,a就是这个宏的展开.

由于ruby没有提供'宏',所以就只能想办法获取caller的所有信息来模拟它.

liusong1111提供的ParseTree估计是一个正确的方向,有时间去研究一下....
9 楼 sunfengcheng 2008-07-29  
有的时候,代码是逻辑,有的时候代码是复制,其实最后代码编写应该是哲学与美学。我们的日本工程师就是这方面的天才
8 楼 baryon 2008-07-28  

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

不好意思,a,b = b,a同你的实现有何不同,望赐教
7 楼 xiaoxizhen 2008-07-25  
a = 100
get_ref_name(a)
传递的是指向100的引用,跟a一点关系都没有,
怎么可能取到a呢。

除了判断值相等,没法判断传的是什么。
如果判断值相等,返回的也只能是数组。
真想知道问GC吧。
6 楼 liusong1111 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.




5 楼 rubynroll 2008-07-25  
Quake Wang 写道
我实在想不出获取变量名的实际用途是什么?
如果是为了类似指针方式获取值,ruby有提供ObjectSpace._id2ref


要说到用处么, 有了它就可以实现类似'宏'的功能, 也有可能对有些meta trick有用处吧. 顺便也看看ruby对代码自省到什么程度, 呵呵~
4 楼 QuakeWang 2008-07-25  
我实在想不出获取变量名的实际用途是什么?
如果是为了类似指针方式获取值,ruby有提供ObjectSpace._id2ref
3 楼 rubynroll 2008-07-25  
<div class='quote_title'>dennis_zane 写道</div>
<div class='quote_div'>
<p>我的一个实现,比较丑陋,通过查找local_variables</p>
<p> </p>
<pre name='code' class='ruby'>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)</pre>
 
<p> </p>
</div>
<p> </p>
<p>用local_variables还是有很大局限性, 例如:</p>
<pre name='code' class='ruby'>a = 100
b = 200
c = a</pre>
<p> 这时</p>
<pre name='code' class='ruby'>eval("#{var}", b) == x</pre>
<p> 这句对局部变量a和c都成立, 因为'=='操作符比较的是值.</p>
<p> </p>
<p>另外,还要挖空心思去给'x'取个特别的名字,要不然 var != 'x' 也很容易被击中.</p>
<p> </p>
<p> </p>
<p>很遗憾的是Kernel#caller没有提供参数列表信息,否则这个问题就好解决了.</p>
<p> </p>
2 楼 ye_jian_hui 2008-07-24  
在ruby层面只能用local_variables来实现了
1 楼 dennis_zane 2008-07-24  
<p>我的一个实现,比较丑陋,通过查找local_variables</p>
<p> </p>
<pre name='code' class='ruby'>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)</pre>
 
<p> </p>

相关推荐

    一个有趣的工具,用于快速浏览维基百科上的无源片段。___下载.zip

    标题中的“一个有趣的工具,用于快速浏览维基百科上的无源片段”暗示我们正在讨论一个软件或应用,它专门设计来帮助用户探索和查找维基百科中未引用的段落,这种工具通常对编辑者或者研究人员非常有帮助,因为它们...

    有趣的实验报告

    标题“有趣的实验报告”可能指的是一个关于IT技术或者编程实践的实验项目,它可能是作者在探索某个技术或解决特定问题时所做的记录。由于没有具体的描述,我们只能根据给出的标签和压缩包内的文件名来推测可能涉及的...

    三位数重排求差“数学黑洞”

    1. 定义一个名为`Digitn`的函数,该函数接受一个整数`x`,以及两个引用参数`max`和`min`。函数的目的是将`x`的各位数字重新排列,使得`max`存储重排后的最大数,`min`存储最小数。在函数内部,我们首先获取三位数的...

    规划你的C#程序

    文章中提到了一个具体的案例:假设有一个名为`Common.dll`的程序集,它同时提供了XML文件操作和数据库操作的功能。后来又开发了一个名为`Configuration.dll`的程序集用于处理配置文件。由于配置文件通常是XML格式,...

    Python练习程序_Python倒叙_

    - `第二章练习题.py`:可能包含了第二章学习的多个问题,其中一个可能涉及字符串或列表的倒序操作。 - `倒叙.rar`:这是一个压缩文件,可能包含了与倒序相关的额外练习或示例代码,需要解压后查看。 - `绘制同切...

    array-abuse:数组很有趣

    3. **元素访问**:通过索引访问元素,如`arr[0]`获取第一个元素,但要注意越界问题。 4. **数组拷贝**:可以使用`System.arraycopy`(Java)或`std::copy`(C++)等函数进行数组拷贝。 5. **多维数组**:在需要...

    55 Ways to Have Fun with Google

    在谷歌上搜索“Kevin Bacon game”,就可以看到相关的游戏和测试,这不仅是一个有趣的社交实验,也展示了谷歌搜索的强大功能。 ### 二十、谷歌字母表 “谷歌字母表”是指谷歌母公司Alphabet Inc.的名字,它由一...

    Javascript讲义(李炎恢)

    - 原型链:JavaScript中实现继承的方式,每个对象都有一个`__proto__`属性指向构造函数的原型。 5. **事件和DOM操作** - 事件处理:`addEventListener`和`removeEventListener`用于添加和移除事件监听器。 - DOM...

    DOS入门教程下载——洪恩在线版

    3. 环境变量:如`%PATH%`用于存储系统路径,`%DATE%`获取当前日期,可以在命令中引用。 六、DOS与文件系统 DOS支持FAT(File Allocation Table)文件系统,包括FAT16和FAT32,用于管理和存储磁盘上的数据。尽管现代...

    Python-wtfpython的中文翻译

    再比如,你可能困惑于Python的列表切片为何可以返回原列表的一个副本,而字典的切片却返回一个迭代器。这是因为列表是序列类型,支持索引访问,而字典是映射类型,其元素无法通过索引获取。 此外,Python的动态类型...

    CRichEditCtrl实现MSNQQ动画表情

    为了在`CRichEditCtrl`中展示动画表情,我们需要实现一个OLE对象,该对象能够加载并播放GIF动画。这里我们将利用腾讯QQ中使用的`ImageOle.dll`库来完成这一任务。 ##### 1. OLE对象概述 OLE(Object Linking and ...

    C语言课程设计-坑爹大冒险.zip

    "坑爹大冒险"可能是一个有趣的项目,通过设计和实现这个游戏,我们可以将理论知识应用到实践中,锻炼解决问题的能力和编程技巧。同时,这样的项目也能帮助我们更好地理解C语言的底层工作原理,为未来的学习和开发...

    PHP内核介绍及扩展开发指南

    `refcount`用于追踪有多少变量引用了同一个`zval`实例,而`is_ref`则标识了`zval`是否表示的是一个引用。引用计数机制使得多个变量可以共享同一份数据,直到最后一个引用消失后,数据才会被释放。 **1.1.3 zval状态...

    C#编程实现简易图片浏览器的方法

    在C#编程中,创建一个简易的图片浏览器可以是一个实用且有趣的项目,它涉及到Windows Forms (WinForm) 应用程序开发。以下是一些关键知识点和实现步骤: 1. **命名空间引用**: 使用 `using System.IO;` 引入了...

    Bazinga:只是开个玩笑〜

    【标题】"Bazinga:只是开个玩笑〜"似乎是一个轻松幽默的引用,可能源自美国热门电视剧《生活大爆炸》中的角色谢尔顿·库珀的经典台词"Bazinga!",通常在他开玩笑时说出。然而,在IT行业中,这个标题可能是在暗示某个...

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    21.11 一个有趣的依赖性问题 21.12 手动监视和控制对象的生存期 21.13 对象复活 21.14 代 21.15 用于本地资源的其他垃圾回收功能 21.16 预测需求大量内存的操作能否成功 21.17 编程控制垃圾回收器 21.18 ...

    CLR.via.C#.(中文第3版)(自制详细书签)

    21.11 一个有趣的依赖性问题 21.12 手动监视和控制对象的生存期 21.13 对象复活 21.14 代 21.15 用于本地资源的其他垃圾回收功能 21.16 预测需求大量内存的操作能否成功 21.17 编程控制垃圾回收器 21.18 线程...

    安卓刮刮乐相关-中秋刮刮乐.rar

    这种应用通常涉及到图像处理、触摸事件处理以及动画效果的实现,对于开发者来说是一个有趣的挑战。 在这个名为“中秋刮刮乐”的项目中,我们可以推测其是一个与中秋节相关的刮刮乐应用。可能包含了节日元素的设计,...

    2021-2022计算机二级等级考试试题及答案No.19799.docx

    - **解释**:在C语言中,可以通过定义一个指向数组类型的指针变量并将其初始化为数组的地址,然后使用`*p`来引用数组的第一个元素。 ### 17. VBA程序中的语句分隔符 - **知识点**:VBA程序中的多条语句可以写在...

Global site tag (gtag.js) - Google Analytics