Ruby学习基础(二) — 杂记

1. String#chomp VS String#strip

首先String#chomp有可选的参数,而String#strip无参。其次,String#chomp在没有参数时,删除的是结尾的\n,\r和\r\n,而String#strip删除的是字符串头部和尾部的空格和换行符;String#chomp有字符串参数时,则将删除原字符串结尾和参数匹配的字符串。
eg:

"Hello world\n".chomp   =>"Hello world"
"  Hello world  ".strip      =>"Hello world"
"Hello world".chomp("world")   =>"Hello "

2. require_relative

看到module语法时,便试着写了个例子:新建了两个module,分别为moduleA.rb 和moduleB,然后在另一个文件中将这两个module引用进来,便使用:

require "moduleA"
require "moduleB"

但是最后在执行过程中出错,提示找不到require的两个文件,最后在ruby-china上寻求帮助,发现用:

require_relative "moduleA"
require_relative "moduleB"

即可解决。

其实require,require_relative,include等并不是Ruby的关键字,而是Kernel的实例方法。而Kernel则被Object类include,所有的对象都是Object类的实例,所以没有接收者。
其实require_relative方法内部还是调用了require方法,其源代码如下:

def require_relative(path)
   require File.join(File.dirname(caller[0]), path.to_str)
end

3. Module作用

Module作用有二:

  • 相当于命名空间,防止名字冲突

  • 实现了mixin功能

Module里面的一般方法定义都是以Module的名字为前缀,或者以self为前缀(self相当于module 的名字),相当于类中的类方法。如果方法不加前缀,则相当于Class中的实例方法,但是Module不是类,不能创建实例,所以不能有实例方法。这时可以在Class的定义中包含Module(使用include)。包含以后,module中定义的实例方法便能像在类中定义一样,可以由类实例化的对象来访问。eg:

module Debug
     def who_am_i?
         "#{self.class.name} (\##{self.id}) :  #{self.to_s}"
     end
end
class Test
   include Debug
end
obj = Test.new("Hello")
obj.who_am_i?

Module中定义的实例变量,在包含Module的Class中也可以进行访问。当然这一举措也会引出问题:如果一个Class中include多个Module,并且这些Module中都定义了相同的实例变量,那么在Class中操作这些实例变量时将难以区分,所以会产生意想不到的错误,所以在Module中一般不使用实例变量,如有特殊情况需要使用,则实例变量名一定要唯一,最常见的做法便是将Module的名字作为实例变量的名字的前缀部分。

而Mix-in则是受限制的多重继承。现在的Ruby只能继承一个类,但是可以通过include继承多个模块。

类 = 模块 + 实例化能力

你可能感兴趣的:(Ruby学习基础(二) — 杂记)