《Ruby语言入门教程v1.0》学习笔记-03

10.09

第七章    

7.1 模块

Ruby标准包里的 Math 模块提供了许多方法,比如:求平方根 sqrt ,使用的时候要这么写:模块名.方法名(参数)。如:Math.sqrt( a*5+b )

Math 模块还提供了两个常量,圆周率π 和自然对数底 e,使用的时候要这么写:模块名::常量名。如:puts Math::PI

定义模块module...end 。模块与类非常相似,但是:
A) 模块不可以有实例对象;
B) 模块不可以有子类。

7.2 命名空间

如你所见,只要include模块名,就能使用不同模块的sqrt方法,Math模块的sqrt方法不能有三个参数,Me模块的sqrt方法可以是一个参数,或者二个参数,或者三个参数。Me模块被include 在Math模块后面,Math模块的sqrt方法就被Me模块的sqrt方法覆盖了。

module Me
    def sqrt(num, rx=1, e=1e-10)
        #num,需要求平方根的目标;rx,迭代区间;e,精度
        num*=1.0
        (num - rx*rx).abs <e ? rx : sqrt(num, (num/rx + rx)/2, e)

    end
end


include Math
puts sqrt(293)                   # 17.1172427686237


include Me
puts sqrt(293)                  # 17.1172427686237
puts sqrt(293, 5, 0.01)     # 17.1172429172153

10.22 

7.3 糅和(Mix-in) 与多重继承

include方法通过“ < 父类名 ” ,一个子类可以得到父类的属性和方法;

                通过“ include模块名 ” ,一个子类可以得到某个模块的常量和方法。类不能被 include 。

extend方法通过“.ectend(模块)”,一个实例对象可以得到某个模块的长了和方法,而不是整个类。

include 方法为一个类的所有对象包含某个模块; extend 方法为一个类的某个对象包含某个模块。

module Me
    def sqrt(num, rx=1, e=1e-10)
        num*=1.0
        (num - rx*rx).abs <e ? rx : sqrt(num, (num/rx + rx)/2, e)
    end
end


class Person
    def talk
        puts "I'm talking."
    end
end


class Student < Person
    include Me
end


aStudent=Student.new    #Student是Person的子类,并且集成了模块Me

aStudent.talk                             # I'm talking.

puts aStudent.sqrt(20.7,3.3)     # 4.54972526643248

module Me
    def sqrt(num, rx=1, e=1e-10)
        num*=1.0
        (num - rx*rx).abs <e ? rx : sqrt(num, (num/rx + rx)/2, e)
    end
end

class Student
end


aStudent=Student.new
aStudent.extend(Me)        #新增的实例继承了模块Me


puts aStudent.sqrt(93.1, 25)     # 9.64883412646315

7.4 require 和 load

Me模块写在文件 E7.4-1.rb中,将 Person类写在文件 E7.4-2.rb中,这时候 Student类如何使用 Me模块和 Person类呢?这里要用到require方法。

require方法包含另一个文件,另一个文件名需要是一个字符串。

require包含文件,只加载一次,遇到同一文件时自动忽略;不同路径下的同名文件会多次加载。

load包含文件,加载多次,即使是相同路径下同一文件。

#E7.4-3.rb
require "E7.4-1"
require "E7.4-2"
class Student < Person
    include Me
end

aStudent=Student.new
aStudent.talk # I'm talking.
puts aStudent.sqrt(77,2)   # 8.77496438739435

#E7.4-4.rb
load "E7.4-1.rb"
class Student
end


aStudent=Student.new
aStudent.extend(Me)
puts aStudent.sqrt(100.1, 12)            # 10.0049987506246

总结一下:
require,load用于包含文件;include,extend则用于包含模块。
require加载文件一次,load加载文件多次。
require加载文件时可以不加后缀名,load加载文件时必须加后缀名。
require一般情况下用于加载库文件,而load用于加载配置文件。
利用load 多次加载文件的特性,可以用来实现程序的无缝升级和系统的热部署。程序功能改变了,你只需要重新load 一次,其它代码与它再次交互的时候,这个程序实际上已经不是原来的程序了。

原文地址:https://www.cnblogs.com/poppyp/p/3358809.html