Ruby系列学习资料(四)
2008-01-25 16:59
211 查看
Ruby系列学习资料(四) 6、Syntax Issues Ruby的解析器是非常复杂和相对宽松的。它试图理解它看到的东西,而不是强迫程序奴隶般地遵循一套规则。然而,这种行为可能采用了一些习惯。这儿列出了你应该知道的Ruby语法: l 用于方法调用的圆括号是可选的。这些调用都是有效的: foobar foobar() foobar(a,b,c) foobar a, b, c l 假设圆括号是可选的,x y z意味着什么,是什么?像它的结果,这意味着, "调用方法 y ,传递z做为参数,然后传递结果做为方法x的参数"。简单说,它与x(y(z))语句的意思一样。 l 让我们试着传递个哈希表给方法: my_method {a=>1, b=>2} 这是个语法错误,因为左花括号被认为是个块的开始,在这种情况下,圆括号是必须的:my_method({a=>1, b=>2}) l 现在让我们假设哈希表是传递给方法的唯一参数。Ruby非常宽松地允许我们省略花括号: my_method(a=>1, b=>2) 有些人可能认为这看起来像是带有命名参数的方法调用,但是它强调不是这样。 l 现在考虑这个方法调用: foobar.345看它,有人可能认为foobar是个对象而345是个被调用的方法,但明显地方法的名字是不能以数字开头的!解析器解释它是对方法foobar的调用,传递数字0.345做为一个参数。这儿,你看到的是圆括号或中间的空格都被忽略了的结果。不用说,事实上你可以用这种方式编码,但这只是你可的暗示。 l 有些情况下空白也很重要。例如,这些表达式的意思似乎是一样的: x = y + z x = y+z x = y+ z x = y +z 事实上第一到第三个是一样的。然而,在第四种情况中,解析器认为y是个方法调用,+z是个传递给它的参数!然后,如果没有名字为y的方法,它将对这一行给出个错误信息。The moral is to use blank spaces in a reasonable way. l 类似地,x = y*z 是y和z的乘法,然而x = y *z 是方法y的调用,传递一个数组z的扩展做为参数。 l 在构造标识符时,下划线被认为是小写字母。所以,标识符可以用下划线开头,但它不能是常量即使下一个字母是大写。 l 线性的,如果语句被嵌套,使用关键字elsif而不像其它语言使用else if 或elif 。 l Ruby内的关键字不是真正的"被保留单词"。在很多情况中,一个关键字可被用于做为一个标识符同时解释器也不会弄混。我们不会说在什么条件下可以或不可以这样做。我们说这些只是认为如果你真的需要的话是可以这做的,警告是这会带来混乱。通常,使用关键字做一个标识符应该小心,应该在你的思想中保持可读性。 l 当然关键字是可选的(在if和case语句中)。为了可读性当然也可以使用它。对while和until循环来说也是一样的。 l 问号和感叹号不是真正的它们可以修改的标识符的一部分,它们应该被认为是后缀。所以,例如尽管chop和chop!被认为是不同的标识符,这些字符不允许在其它的地方使用。同样,我们在Ruby内使用defined?,但defined是关键字。 l 在一个字符串内部,英磅符号(#)被用于表示被计算的表达式。这意味着在很多情况下,当英磅符号出现在一个字符串内时,它必须用反斜线表示法来转义,但是这只在下一个字符是左花括号 ({), 美元符号 ($), 或"at"符号(@)时。 l 三元操作符 (? ,它起源于C语言,在Ruby中有时也称为"未文档化的"。基于这个理由,程序员可以不愿意使用它 (尽管我们并不回避它)。 l 由于事实上问号可以被附加给标识符,所以应该小心要在三元操作符上加上空格。例如,假设我们有变量my_flag,它即保存true也可保存false。然而第一行代码是正确的,而第二行代码将产生语法错误: x = my_flag ? 23 : 45 # OK x = my_flag? 23 : 45 # 语法错误 l The ending marke用于植入文档的标记 =end不应该被当成一个记号。它标记完整行;所以,行内的其它字符不会被认为是程序的一部分,但是它们属于被植入的文档。 l Ruby内的块不是任意的,也就是说,你不能像C那样凭感觉来开始一个块。块只允许出现在需要它们的地方(例如,附加给迭代器)。这也是为什么Ruby内的post-test循环使用一个begin-end对的原因,即使不进行异常处理。 l 记住关键字BEGIN 和END与begin 和 end 关键字是完全不同的。 l When strings bump together (static concatenation), the concatenation is of a higher precedence than a method call. Here's an example: # These three all give the same result. str1 = "First " 'second'.center(20) str2 = ("First " + 'second').center(20) str3 = "First second".center(20) Precedence is different. l Ruby有几个伪变量,像起来像局部变量但它们用于特殊目的。它们是self, nil, true, false, __FILE__, 和 __LINE__. 7、Perspectives in Programming 大概每个人都知道Ruby在过去曾是个学生或其它语言的用户。这个经历使用学习Ruby变得较为容易,Ruby内的许多特性与其它语言内相应特性相似。换句话说,程序员可能被Ruby内这熟悉的结构带入到一种虚假的安全感觉中,它们会用以前的经验来使用这些结构。 大多数人认为Ruby来自于Smalltalk, Perl, C/C++, 和其它语言。Their presuppositions and expectations may all vary somewhat, but they will always be present. For this reason, here are a few of the things that some programmers may "trip over" in using Ruby: l 实际上Ruby内的字符是个整数。它没有自己的类型,也不会被认为是长度为1的字符串。考虑下面代码片断: x = "Hello" y = ?A print "x[0] = #{ x[0]} n" # Prints: x[0] = 72 print "y = #yn" # Prints: y = 65 if y == "A" # Prints: no print "yesn" else print "non" end l 和其它很多语言一样没有Boolean类型。TrueClass 和FalseClass是截然不同的类,它们的实例化是ture和false。 Ruby的很多操作符类似或等同于C中的。有两个值 得注意的例外是增量减量操作符 (++ 和 --)。它们在Ruby中是无效。 l 模数操作符在对待负数上不同的语言有些差别。这种观点的讨论都超出了本书的范围;但可以说Ruby有下面这样的行为: 5 % 3 # Prints 2 -5 % 3 # Prints 1 5 % -3 # Prints -1 -5 % -3 # Prints 2 l 有些人习惯地认为false值可以用0,空字符串,空字符,或其它东西。但是在Ruby中,所有东西都是true;事实上除了false和nil每个东西都是true。 l Ruby总是反复强调:变量没有类型;只有值才有类型。 l 说变量未被定义(例如,变量没有声明)本质与说它是nil是一样的。这样的值会通过与nil的等同性测试并且如何在一个条件中单独使用它将计算出false。这个原则在哈希表中是个例外,因它存储在哈希表中的nil是有效值,与nil比较以在哈希表中找是否存在值是不适当的。(通过方法调用手段,有几个正确的方式可以完成这个比较。) l 记住post-test循环在Ruby内可以通过跟随在while或until的修饰符形式后面的一个begin-end结构来模仿。 l 记住Ruby内没有变量声明。然而,给变量nil初始值是个好习惯。这的确没有赋给变量类型并且也没有真正地初始化它,但它通知解析器这是个变量的名字而不是一个方法的名字。Ruby解释一个标识符为一个方法名字,除非它看到早先赋值个名字的引用给变量。 l 记住 ARGV[0] 是命令行的第一个参数,编号自然从零开始;前面提到的参数不是文件或脚本的名字,如C中的argv[0] 。 l 大多数Ruby的操作符是真正的方法;这些方法的点形式提供了熟悉和便利。第一个例外是一套反身赋值操作符(+=, -=, *=, 等等);第二个例外是下面这些: = .. ... ! not && and || or != !~ l 像大多数(尽管不是全部)现代语言,Boolean操作总是短路;即,Boolean表达式的计算在它是true值时停止。在or操作符序列内,第一个true将停止求值;在有and操作符的字符串内,第一个false将停止求值。 l 记住前缀@@用于类变量(它与类关联而不是实例)。 l 记住loop不是关键字;它是一个Kernel方法,不是一个控制结构。 l 有些人会发觉unless-else句法有点违反直觉。因为unless是if的反面,如果条件为false则else子句会被执行。 l 通常传递给方法的参数其实是一个对象的引用;同样,参数有从方法内部被修改的潜在可能。 l 简单的Fixnum类型被做为直接值传递,所以它不可能在方法内部被修改。true,false和nil也是一样。 l 不要混淆&& 和 || 操作符与& 和 | 操作符。它们的用法与C语言类似;前者用于Boolean操作,后者用于算术或位操作。 l 这儿是在&&-||操作符以及and-or操作符之间的区别。前者用于更普通的用途,在一个表达内的结果不是true或false。后则的结果则总是true或false;它们被明确地用于条件内连接Boolean表达式 (所以如果一个表达式不能计算出true或false时会有语法错误)。看下面代码片断: print (false || "string1n") # Prints string1 # print (false or "string2n") # Syntax error! print (true && "string3n") # Prints string3 # print (true and "string4n") # Syntax error! print (true || "string5n") # Prints true # print (true or "string6n") # Syntax error! print (false && "string5n") # Prints false # print (false or "string6n") # Syntax error! l and-or 操作符比&&-|| 操作符有较小优先级。看下面代码片断: a = true b = false c = true d = true a1 = a && b or c && d # &&'s are done first a2 = a && (b or c) && d # or is done first print a1 # Prints false print a2 # Prints true l 另外,要小心赋值操作符有比and或or操作符高的优先级!(反身赋值操作符+=,-=和其它也是一样的。)例如,下面代码的第三行看起来像个普通的赋值语句,但它其实是个free-standing表达式 (事实上,等同于第五行。)。第七行是个真正的赋值语句,它才是程序员真正想要做的: y = false z = true x = y or z # Line 3: = is done BEFORE or! print x, "n" # Prints false (x = y) or z # Line 5: Same as line 3 print x, "n" # Prints false x = (y or z) # Line 7: or is done first print x, "n" # Prints true l 不要混淆对象属性和局部变量。如果你习惯于C++或Java,你可能忘记这一点。变量@my_var是你写的类的上下文环境内的实例变量(或属性),但是同样环境下的my_var则只是那个上下文环境内的局部变量。 |
相关文章推荐
- Ruby系列学习资料(一)
- Ruby系列学习资料(二)
- Ruby系列学习资料(三)
- ruby学习系列--使用SOAP
- ruby watir 学习资料汇总
- WPF入门教程系列一——基础 一、 前言 最近在学习WPF,学习WPF首先上的是微软的MSDN,然后再搜索了一下网络有关WPF的学习资料。为了温故而知新把学习过程记录下来,以备后
- 【WPF学习笔记】之如何把数据库里的值读取出来然后显示在页面上:动画系列之(六)(评论处有学习资料及源码)
- ruby学习系列--获取当天修改的文件信息
- [译林系列--Ruby] 通过IronRuby和C#学习Ruby[2]
- libcef学习最详细的入门资料系列之一 :libcef基本的入门知识
- Extjs系列学习资料
- [译林系列-ruby]通过IronRuby和C#学习Ruby[1]
- 【Xamarin挖墙脚系列:学习资料大放送】
- 【Ruby】学习资料
- 机器学习系列1-学习资料和学习路线
- Framebuffer原理、使用、测试系列文章,非常好的资料,大家一起学习
- OSGi 入门开发学习资料必读系列
- 目标检测CNN系列学习资料汇总(2014-2017)
- ArcGIS教程下载 系列 ArcMap教程下载 ArcCatlog 教程下载 等的学习资料下载 (google文档 可以直接查看 也可以下载)
- 学习Cloudera Hadoop 4系列实战课程资料