理解Ruby中的标志(Understanding Ruby Symbols)

翻译 2006年06月24日 20:46:00
理解Ruby中的标志(Understanding Ruby Symbols)
原文出处:http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols
翻译:Suninny AT Gmail.com

标志在Ruby中是一个迷。我们用她,但多数人并不真正懂她。
什么是标志?
简单来说,标志是你用来代表名字或字符串的一个东西。这可以归结为一种高效的描述名--产生单一的字符串用于每个命名实例,这样就节省了空间。
琼斯博士的案例
琼斯博士(Dr Jones)是个心理学家。 他通常使用语词联想试验诊断患者,并且使用Ruby记录一切。 他的第一名患者Why来到了这里:

Dr J: Red
Why : Ruby
Dr J: Transportation
Why : Rails
Dr J: Chunky
Why : Bacon

琼斯博士建立一个散列来存储这些数据:

 why = {"red" => "ruby", "transportation" => "rails", "chunky" => "bacon"}

问题所在

在进行几百个语词联想试验之后,琼斯博士开始意识到他用尽了内存! 于是琼斯在irb进行测试:

> patient1 = { "ruby" => "red" }
> patient2 = { "ruby" => "programming" }
> patient1.each_key {|key| puts key.object_id.to_s}
211006
> patient2.each_key {|key| puts key.object_id.to_s}
203536

我们看到,每次他建立一个散列来存储信息,Ruby就在不同的内存位置为每个键建立了一个新的字符串对象。

幸运的是,我们还有其他的方法。

用标志来突围

不同于字符串,在一个Ruby会话期间,同一个名称的标志只作一次初始化然后就存在于内存中。当你需要重用字符串来表示其他东西时,标志是再适合不过的了。重做琼斯博士的测试,我们能直接观察到:

> patient1 = { :ruby => "red" }
> patient2 = { :ruby => "programming" }
> patient1.each_key {|key| puts key.object_id.to_s}
3918094
> patient2.each_key {|key| puts key.object_id.to_s}
3918094

通过使用标志,在语词联想试验中我们用单一的内存地址代表了“ruby”这个单词。随着时间的推移,这能节省下大量的空间。
标志的其他应用场合
无论何时,只要你是重用一个单词来反复代表其他东西,标志就能派上用场。不管是散列中的一个键,还是Http查询中的一个方法。在最新、最伟大的Web框架--Ruby on Rails的路由和链接中就应用到了标志。

在表现一个网页之前,Rails会执行框架内部的控制器(controllers)中定义的动作(actions),因此在Rails中,链接就像这样表示:

link_to("View Article", :controller => "articles", :action => "show", :id => 1)

当一个应用可能至少有数百个链接,或者说有数百个不同动作和控制器的引用时,使用标志就比使用字符串高效得多。

最后,值得注意的是标志的应用场合并不局限于散列中的键。例如,如果你写一个Http客户端(或服务器),在这个程序中,可能需要多次用到get和post:

do_this if query == :get

...
send_message_to_server(:post,filename)

当需要反复用到一个字符串时,标志或许是一个蛮不错的替代品。

更新
在Freenode(译注:一个著名的IRC服务器)的ruby-lang频道,Aria和Nome为这篇文章给出了有用的增补。

11:58 < Aria> 同样,即便完全出于现实方面的考虑,使用标志也很理想:如果你要引用一个方法名,就用标志吧,因为她总会在那里(在定义了方法之后)。
12:03 < nome> Kevin Clark:标志的目的是用来辨别构造(主要是用户级的):散列中的槽、一个方法、一个选项等等。

同样,Aria还回应了Geoff在注解中提出的问题:

Geoff:我很想知道1000个字符串"red"究竟要比:red耗费多少内存。记住,在Rails之外,"red" != :red

Aria:多少内存?20字节/对象,加上存储数据的3个字节,再加上存储长度的4个字节,一共是27×1000=27000个字节。与此相对,标志表条目的一份拷贝,只需几个字节。

Jim Weirich 写到:
我通常有下面的法则来比较字符串和标志:
(1) 如果侧重于对象的内容(即字符序列),就用字符串;
(2) 如果侧重于对象的身份,就用标志。

理解ruby中的标志(Understanding Ruby Symbols)(转)

理解Ruby中的标志(Understanding Ruby Symbols) 原文出处:http://glu.ttono.us/articles/2005/08/19/understanding-ru...
  • zhw161541
  • zhw161541
  • 2007年04月24日 21:44
  • 296

Understanding Ruby Symbols(Ruby标识符的理解)

Posted by kev Fri, 19 Aug 2005 22:11:00 GMTSymbols in ruby are an enigma. We use them, but many don’...
  • P_N
  • P_N
  • 2008年08月19日 20:46
  • 713

理解 Ruby Symbol (Ruby中的冒号)

Symbol 是什么 Ruby 是一个强大的面向对象脚本语言(本文所用 Ruby 版本为1.8.6),在 Ruby 中 Symbol 表示“名字”,比如字符串的名字,标识符的名字。 创建一...
  • besfanfei
  • besfanfei
  • 2012年09月11日 13:27
  • 19370

Ruby之self详解(一)详细剖析

Ruby之self详解(一)详细剖析 博客分类: Ruby_and_Rails CC++C#RubyITeye   简单来说,ruby中的self的含义,要看其上下文。 ...
  • autumn20080101
  • autumn20080101
  • 2012年11月09日 20:15
  • 2700

ruby好像有指针啊!!!

b = "123"a = bb.gsub!(/2/,"")puts a 得到的结果是13,发现如果a = b的话貌似只是把b的指针给了a,但是如果b的值发生了变化a才能从b中独立出来。如果把上面的代码...
  • TIANYA8800
  • TIANYA8800
  • 2010年04月15日 16:39
  • 1060

Ruby——双引号引用里面反斜线转义表

这是截图一本书上的,先存着以便日后方便查看。
  • chiuan
  • chiuan
  • 2011年11月21日 10:12
  • 4115

Ruby中 split 方法

split 方法 ==> 把字符串拆分成有三个元素的数组Date.today => Wed, 15 Feb 2017 2.3.0 :002 > Date.today.to_s => "20...
  • XIAO_XIAO_C
  • XIAO_XIAO_C
  • 2017年06月01日 10:51
  • 462

Ruby中的关键字nil

1.python中的关键字nil     Ruby中的nil和python中的None类似。    nil是一个特殊的值,表示对象不存在。像在正则表达式中表示无法匹配成功一样,方法不能返回有意义的值时...
  • wangjianno2
  • wangjianno2
  • 2016年06月18日 03:05
  • 609

Ruby中关于单引号和双引号的转义

单引号转义 双引号
  • u014749470
  • u014749470
  • 2014年04月17日 11:22
  • 3478

ruby and 和 && 是不同的

http://www.themomorohoax.com/2008/12/08/and-vs-amperand-in-ruby >> alien = true >> speaks_english =...
  • dazhi_100
  • dazhi_100
  • 2014年12月02日 15:00
  • 1696
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:理解Ruby中的标志(Understanding Ruby Symbols)
举报原因:
原因补充:

(最多只允许输入30个字)