`
taito
  • 浏览: 94500 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Ruby 源代码--[Ruby ソースコード]中文版--第八章Ruby语言的详细

阅读更多
当你看到这个标题时一定会好奇为什么是从第八章开始。实际上是这样的,之前在网上听到同是Ruby的爱好者说起,一直想拜读号称Ruby圣典[Rubyソースコード]一书,只可惜它是日本人写的,正苦脑中。而我刚好又会那么一点点Japanese,所以就"光荣"的接过了此项任务(骨子里好像有雷峰精神)。

不过当我翻译到一半的时候,才发现这是一项艰苦而又漫长的工作。不仅即要用中文准确表达作者的意图,还要让每一个有关专业术员的地方是合呼逻辑的。(累啊!我的业余时间就这样奉献了)

至于为什么是从第八章,是因一个朋友说从第八章开始吧,可能是前面都很好理解了。所以就这么定了。(去掉了七章,也许会轻松一些吧 - -~)

下面就开始吧,有不对的地方请大家多多包涵,欢迎指正!

原文地址是:http://i.loveruby.net/ja/rhg/book/
译文时时更新的地址是:http://www.doruby.com

============================================
第8章 Ruby语言的详细介绍 | 2008年11月1日 20:00 更新
============================================
到现在为止都还没对Ruby语言进行详细结构和评价的描述。因为没有想过做完整的说明,本书所有的方法细节全部剪切掉了。所以即使读到这里的话,想开始用ruby开发的话,还是不太可能的。如果想要完整的资料的话,附带有一个关于操作手册的CD-ROM(Ruby操作手册CD-ROM附件下载地址archives/ruby-refm.tar.gz},请读一下。

已经很了解Ruby的读者可以跳过这部分。

语法(Literal)

Ruby语法有非常直观的表现形式。 Ruby作为脚本语言,第一是具备很高的水准,第二笔者认为是语法的表现力,第三是拥有了丰富的基础类。

即使是简单的语法就已经非常强大,如果组合起来使用就会变的更强。特别是由HASH和数组的组合,可以表达复杂的语法,这是它最大的长处。即使是正规表达式,数组,HASH等什么都可以写出很漂亮的语句。

具体它是如何做到的,请看下面。

字符串
首先字符串和正规表达式是脚本所不可缺少的。字符串的表现形式同样在Ruby中丰富多彩

单引号字符串

'string'              # 「string」
'\\begin{document}'   # 「\begin{document}」
'\n'                  # 「\n」反斜杠和n 。不换行
'\1'                  # 「\1」反斜杠和1
'\''                  # 「'」

最简单的表达形式。在C语言中只是有被单引号包函的字符,而Ruby没有限定。它统称为「'字符串」。对于[\]和[']要使他们变的有效加上反斜杠即可。其它的字符加上反斜杠也同样保留他原来的意思(参照第四章的例子)

其次,Ruby的字符串即使换行也不会被分段。它会表示为包含了换行符的字符串使用。

'multi
    line
        string'
而且ruby命令中加上-K选项,可以支持多语言。现在对应的有EUC-JP(-Ke)、 Shift JIS(-Ks)、UTF8(-Ku)三种。

'「漢字が通る」和「ルチバイト文字が通る」稍微不一样'

双引号字符串

"string"              # 「string」
"\n"                  # 换行
"\0x0f"               # 16进制字节表示
"page#{n}.html"       # 内嵌表达式


引号变了后表达式和「反斜杠(backslash)记法」使用方法一样。所谓反斜杠记法是指像C语言一样一些古老的标记方法,如换行的\n啦,空格的\b啦等。 Ruby除此之外对于Ctrl-C,ESC标记也非常方便。但是列举这些意义不大,所以这里就省略了。

另一方面更历害。「#{ }」中可以书写任意的Ruby式子, 执行时,只要是审核过的字符串都可以放入,一个变量,一个方法等都没有限定。这样的把所有语法全部表示出来也被称做是一句式。

"embedded #{lvar} expression"
"embedded #{@ivar} expression"
"embedded #{1 + 1} expression"
"embedded #{method_call(arg)} expression"
"embedded #{"string in string"} expression"

%字符串
%q(string)            # 和'string'相同
%Q(string)            # 和"string"相同
%(string)             # 和%Q(string)相同、同样也有"string"的意思


一想到字符串中很多包含本身用来区分字符串的字符,即使用escape码("和')等就非常麻烦。这时,使用%就可以方便的做到自动识别。下面列举了「"」字符串和「%」字符串不同的表示方法。

"<a href=\"http://i.loveruby.net#{path}\">"
%Q(<a href="http://i.loveruby.net#{path}">)



同样的字符串,%字符串表达方法看起来更好一些,escape码(",')的增加也变的很少,对于这样的字符串来它变的更有用处。

这里不仅可以用()区分字符,也可以用[],{},##等标记。用%也没关系。

%q#this is string#
%q[this is string]
%q%this is string%


here-document

here-document是指以行为单位的字符串结构。普通的字符串从开始的"到结尾的"为记号、而here-document开始是有<<EOS的行开始,结尾是有EOS的行为结尾。

"開始文字と終端文字の間にある文字が文字列。"

<<EOS
開始行と終端行の
間にある行が
ヒアドキュメント。
EOS
阴影部分即是here-document。 这里是用EOS表示,实际上你用什么英文单词都可以,严格的说,[a-zA-Z_0-9]字符都可以

here-document的特征是、字符串用「有开始记号和终止记号的行」作为区分。在有开始记号的行做为开始。所以在开始开始记号在行的位置并不太重要。通俗的说,就是在表达式中无论是中间部分还是其它任意位置都是可以的。

printf(<<EOS, count_n(str))
count=%d
EOS
像这种时候、「count=%d\n」作为字符串被赋予了<<EOS位置的值。等同于下面的这句。

printf("count=%d\n", count_n(str))
对开始记号位置的随意来说,终止记号就相对要严格了、行的开头不能放置任何内容,一切其它无关的字符都不行。 但是向下面这样在开始记号处加入了负号的情况下,如<<-EOS可以使缩进字符串同样是有效的。

     <<-EOS
ヒアドキュメントの内容自体をインデントできたら
さらに便利だろうなあ。でもできないんだなあ。
そういうときは適当にメソッド書いてインデントを
消すのが定石です。ただしタブには注意。
     EOS
而且如果在开始记号处加上""和''后,字符串的性质也可以发生变化。例如<<EOS一但变成<<"EOS"后可以放入各种斜线标记法。

    <<"EOS"
一日は#{24 * 60 * 60}秒に決まってます。
うそです。
EOS
那么要是<<'EOS'这种'字符串是一样的吗?出呼意外他们完全不一样、他变成「完全的字符语义」。而且里面所有的有关转义字符串功能都无效。这样要显示源代码的话就很方便。

在第二部分也有对于here-document源码的解释,要想具体了解的话,可以试着读下。

字符
Ruby的字符串是由字节而来、如于字符这样的对像是没有的。另一方面、用下面的方法,可以指定字符的ASCII码(整数)。
?a                    # 「a」相对的ASCII整数
?.                    # 「.」相对的ASCII整数
?\n                   # LF
?\C-a                 # Ctrl-a


正规表达式/regexp/
/^Content-Length:/i
/正規表現/
/\/\*.*?\*\//m        # 相当于C的命令
/reg#{1 + 1}exp/      # 和/reg2exp/相同
两个斜线所包含的内容即是正规表达式。对于正规表达式中字符串不同的组合,表达不同的意思。例如

/abc/
所表达的是、匹配「有a、其次有b、再其次有c的字符串」。也就是"abc"、"fffffffabc"、 "abcxxxxx"都是匹配的。

还可以指定更为特殊的应用。

/^From:/


如果是这样的话、「从行的开始From:之后的字符串」都会匹配。这样的表达方式还有很多、即便是相当复杂的模式也可以做成。

使用方法有无数种。变换区分匹配的字符串、抛开匹配部分、确定是否匹配等等。

而且说到具体用途,如从mail中取出From:标题行、从\n换行字符变换成\r、以及验证字符串中mail地址等等都是可以的。

因正规表达式本身是一个独立的语言体系,ruby中有一个特别的[正规表达式解释器],在ruby是regex.c。所以对于ruby而言,即便从ruby程序中分离正规表达式的部分也是可以的。 结果就是它的文法使用也和字符串的使用差不多,像escapce,斜线记法,表达式的嵌套,等功能都可以照样使用。

但是所说的使用上同字符串一样,实际完全是针对于「Ruby语法结构」上的一个方面。因为之前所说的它是自成的一个语系,当然也得遵循这个语系的规则。就光是对正规表达式的说明就可以出一册书了,所以如果你想了解更多的话还是读下其它的书,比如O'Reilly(网址是http://www.oreilly.co.jp/)的『詳説正規表現』 {『詳説正規表現』Jeffrey E.F.Friedl著、"歌代和正"翻译校验、"春遍雀來・鈴木武生"共译、O'Reilly・Japan、1999}。

%正规表达式
这和字符串一样、在遵循正规表达式的同时也带上%所具有的上述功能。 %r是他的正规表达式形式。这是举的几个比较好的例子。

%r(regexp)
%r[/\*.*?\*/]            # 同C命令一样
%r("(?:[^"\\]+|\\.)*")   # 同C命令一样
%r{reg#{1 + 1}exp}       # 表达式的嵌入

数组

用[]来包含用逗号区分的列所组成的样式即是数组语义。

[1, 2, 3]
['This', 'is', 'an', 'array', 'of', 'string']

[/regexp/, {'hash'=>3}, 4, 'string', ?\C-a]

lvar = $gvar = @ivar = @@cvar = nil
[lvar, $gvar, @ivar, @@cvar]
[Object.new(), Object.new(), Object.new()]
Ruby的数组(Array)的列可以是任意的对像。于是即便是语法中的点到表达式都可以被用做要素。正如前面所说「正规表达式的HASH的数组」无论什么样的内容都可以简单的实现、对于语法无伦是变量或方法都可以随意组合,写起来很漂亮。

还有要注意它也同其它的语法一样,「数组也是一个对像」这个特点。

i = 0
while i < 5
  p([1,2,3].id)    # 每次返回不同的ID对像
  i += 1
end


WORD排列
在写脚本时,因为要用到字符串的排列,现在就可以特别简单的实现这个功能。那就是%w。看下例子就知道了。

%w( alpha beta gamma delta )   # ['alpha','beta','gamma','delta']
%w( 月 火 水 木 金 土 日 )
%w( Jan Feb Mar Apr May Jun
    Jul Aug Sep Oct Nov Dec )
现在表达式中可以用%W。 这是最近才特别加入的功能。

n = 5
%w( list0 list#{n} )   # ['list0', 'list#{n}']
%W( list0 list#{n} )   # ['list0', 'list5']
对于笔者来说仍没想到%W的用途。

HASH
HASH表是任意的类似对像,能够记忆一对一关系的数据结构。下面写了几个相关的表达示。

{ 'key' => 'value', 'key2' => 'value2' }
{ 3 => 0, 'string' => 5, ['array'] => 9 }
{ Object.new() => 3, Object.new() => 'string' }

# 当然多行也是可以的
{ 0 => 0,
  1 => 3,
  2 => 6 }
关于HASH在第3章『名字和名字表』就已经做过详细说明。对于HASH值被分散在存储器中,形成高速检索的表。根据Ruby语法的结构key值也有是任意的表达式的特点。

并且、即使是方法调用的变量是空的话也可以用{...}直接写。

  some_method(arg, key => value, key2 => value2)
# some_method(arg, {key => value, key2 => value2}) と同じ
这个功能可以模仿名字付给变量(keyword变量)的事务。

button.set_geometry('x' => 80, 'y' => '240')
当然这时set_geometry要是可以接受HASH值的。要是真正的keyword变量参数是可以变换的。这里只是一个[もどき](我翻译的是山寨版的意思)。

范围(Range)

范围的语法对于其它的语言来说没有太大变化。 生成Range对像的形式有。

0..5          # 从0到5(包含5)
0...5         # 从0到5(不含5)
1+2 .. 9+0    # 从3到9(包含9)
'a'..'z'      # 字符串从'a'到'z'(包含'z')

小数点在有两个的情况下包含两个终端(起始)要素,三个的情况除外。不管是小数的范围,字符串的范围也好,你能想到的任意相关的对像范围都可以做为Range。但是这样的范围,包括对像的类也好,Range类(即库)的方法也好,前提是没有语法问题。从语法上用..可以连接任意的表达式,但假如在得到结果的对像内不能形成范围,会在执行时发生错误。

另外、..和...的优先级要特别低一些,所以会出现一些意外的情况。

1..5.to_a()   # 1..(5.to_a())
笔直认为Ruby的文法虽然已经相当的合理性,但只有这里不太喜欢。

符号(symbol)
对于符号在第一部已经讲了很多了。即是和任意的字符串形成一个一对一关系的东西。Ruby程序中这个符号用「:」表示。

:identifier
:abcde
这是很普通的例子,实际上,即使是一个变更名,或方法名,都可以用「:」来表示符号。例如。
:$gvar
:@ivar
:@@cvar
:CONST
而且、还可以用什么都没有的方法名如[]和attr=都可以使用。

:[]
:attr=
一旦使用这样的符号中的值,光看起来就相当的麻烦。

数值
最没意思的就是这里了。暴强的一亿表示方法

1_0000_0000
这中间用下划线来区分这个值。正因没什么意思,决定在本书介绍完这个后就把它忘的一干二净。

....... 未完待续
3
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics