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继承多个模块。
类 = 模块 + 实例化能力
网友评论