好久没有支持小废了。 今天发一些Ruby语法系列文章,这是第一部分:
--------------------------------
一。
大家都知道:
foo( a, b, c )
foo a, b, c
上面两组分别是相同的写法,对于一个方法,括号是可以省略的。
插播: 关于诗歌模式(poetry model), 括号可以省略属于诗歌模式,这是Ruby术语,就是省略不必要的标
点符号。
现在有三个方法,
>> def x(a)
>> puts "i m a"
>> end
>> def y(b)
>> puts "i m b"
>> end
>> def z
>> puts 'i m c'
>> end
那么:
>> x y z
会输出什么?
(irb):28: warning: parenthesize argument(s) for future version
i m c
i m b
i m a
=> nil
看结果,x y z 相当于 x(y(z))
Ruby解释器会尝试理解它发现的内容,这是Ruby的魅力。但是像x y z这样的写法,是不容易被读懂的,有的人可能会理解为x有两个参数y,z 所以该上括号的时候还是用括号,我们可以这么写
>> x y(z)
i m c
i m b
i m a
=> nil
这样解释器就不会发出警告了。
在什么情况下一定要使用括号呢?
>> def get h
>> puts "i m hash" if h.is_a?(Hash)
>> end
如果你这么调用:
>> get {:a => 1}
会报错,这个时候左括号{ 会被认为是代码块的开始。
>> get ({:a => 1})
i m hash
=> nil
如果hash是唯一的参数,可以省略大括号。
>> get(:a => 1)
i m hash
=> nil
二。
请问:_COUNTES = 1
这个_COUNTES是不是常量 ?
提示,创建标识符时,下划线是按小写字母处理的。
三。
请问: nil? 和 chop!这种带有问号和叹号的方法中, 问号和叹号是标识符的一部分吗?
提示, 如果是标识符的一部分,那么是可以把问号和叹号放到标识符的任意一个位置的,但是那是不允许的。
四。
self , nil , true, false, _FILE_, _LINE_ 是伪变量。看起来像局部变量,实际是有特殊的用途。
五。
str = "First" 'second'.center(20) 和 str = "First" + 'second'.center(20) 相同吗 ?
提示, 字符串静态拼接的时候,拼接的优先级要低于方法调用。
六。
如何得到一个字母的ASCII码 ?
>> ?A
=> 65
>> ?a
=> 97
七。
Ruby中, 在一系列的or运算中,第一个trun将计算结束。 在一系列的and运算中,第一个false将计算结束。 &&, || 和 and,or的区别是优先级之间的区别, and or 的优先级低于赋值运算。
b = false
c = true
a1 = b || c ->> puts a1 --- true
a2 = b or c ->> puts a2 --- false
八。
>> def aaaa
>> case "Hello"
>> when /Hell/
>> puts "matched"
>> else
?> puts "didnt matched"
>> end
>> end
=> nil
>> aaaa
matched
=> nil
>> def bbb
>> case /Hell/
>> when "Hello"
>> puts "matched"
>> else
?> puts "didnt matched"
>> end
>> end
=> nil
>> bbb
didnt matched
导致这样不同的原因是因为 关系运算符(===) , x === y 和 y === x 是不同的行为造成的。
九。
a = 1 , 我说a这个变量的类是Integer,对吗?
十。
关于范围。 5..10, 包括10 , 5...10不包括10.
a = 5.. 10
b = 5 ... 10
>> a.end
=> 10
>> b.end
=> 10
>> a.last
=> 10
>> b.last
=> 10
>> a.exclude_end?
=> false
>> b.exclude_end?
=> true
>> a.include?(10)
=> true
>> b.include?(10)
=> false
十一,
交换两个变量的值: x, y = y, x
十二,
反身赋值运算符不是方法也不是真正的运算符,它是语法糖,或者说是一种缩写。
所以 x += y 和 x = x + y是等价的
如果+运算符被重载,那么 += 也相当于被重新定义了。
众所周知,反身赋值运算符不能用于初始化变量。 但是我们可以使它有这个功能:
def nil.+(other)
other
end
>> x += 1
=> 1
>> b = 1
=> 1
>> x += b
=> 2
十三,
代码块使用大括号和do-end时候有优先级的差别:
>> def my(a, b)
>> puts a
>> end
=> nil
>> def oo(&block)
>> yield
>> end
=> nil
>> my "h", oo do
?> puts "yes"
>> end
LocalJumpError: no block given
>> my "h", oo {puts "yes"}
yes
h
=> nil
{}只找离自己近的那个方法体,do-end找的是顶级的方法体。
十四,
each的别名是each_line, 因为each是按行操作的。
字符串从某种意义来说也是二维的,可以视其为字符序列或行序列,那么:
>> str = "i love u"
=> "i love u"
>> str.each {|v| puts v}
i love u
十五。
关于闭包。闭包会记住创建它时的上下文,使用Proc对象是创建闭包的一种方式。
我们先定义一个Proc对象
>> def show_me_the_power(param)
>> proc { |base| base ** param}
>> end
=> nil
我们用它来创建一个计算一个数平方的闭包环境:
>> square = power(2)
=> #<Proc:0x0036ddb4@(irb):51>
创建一个数立方的闭包环境
>> cube = power(3)
=> #<Proc:0x0036ddb4@(irb):51>
闭包知道创建它时传递给它的冥值(2,3)
调用闭包来计算11的平方和立方:
>> a = square.call(11)
=> 121
>> b = cube.call(11)
=> 1331
十六,
还是关于闭包。
有这么一个例子:
foo = nil
1.times do
x = 5
foo = Proc.new{puts "In foo, x = #{x} "}
end
x = 1
foo.call 会打印什么 ?
>> foo.call
In foo, x = 5
=> nil
在上面的例子中, foo被初始化为nil,所以在代码块中它不会被定义为局部变量。但是x是代码块里的局部变量,当foo.call的时候,闭包被创建, 当外部的一个x = 1产生的时候,不会影响到闭包里面的x,这是两个不同的变量,所以会输出 x = 5.
十七。
听过类变量,听过实例变量,你们听过类实例变量没有 ?
通常以@打头的变量通常是实例变量,但是如果是在方法外定义的,则为类实例变量(class instance variable)
>> class Myclass
>> @x = 1
>> @y = 2
>> def mymethod
>> @x = 3
>> end
>> end
=> nil
@y 为类实例变量,实际上是类Myclass的属性,而Myclass又是类Class的实例。
>> mc = Myclass.new
=> #<Myclass:0x3951ac>
>> mc.instance_variables
=> ["@x"]
>> Myclass.instance_variables
=> ["@y", "@x"]
在实例方法里是不能引用类实例变量的。
请注意类实例变量是不同于类变量的。
©著作权归作者所有:来自51CTO博客作者blackanger的原创作品,如需转载,请注明出处,否则将追究法律责任
Alex学Ruby职场Ruby
共同学习,写下你的评论
评论加载中...
作者其他优质文章