手记

Alex学Ruby[关于Ruby,你知道吗?]


好久没有支持小废了。 今天发一些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


0人推荐
随时随地看视频
慕课网APP