mymodule 数学工具模块教程

本教程基于 mymodule.luamodule_example.lua 文件,详细介绍 mymodule 数学工具模块的使用方法和功能。

目录

  1. 模块概述
  2. 模块常量
  3. 模块函数
  4. 模块的导入和使用
  5. 模块函数的错误处理
  6. 模块的扩展
  7. 模块的缓存机制
  8. 示例代码
  9. 最佳实践

1. 模块概述

mymodule 是一个 Lua 数学工具模块,提供了各种数学计算功能,包括几何计算、数学函数、素数判断、斐波那契数列生成、最大公约数和最小公倍数计算、角度和弧度转换等。

该模块采用了 Lua 标准的模块编写方式,通过返回一个包含所有函数和常量的表来实现。模块内部还包含了参数验证功能,确保函数接收到有效的输入。

2. 模块常量

mymodule 模块定义了以下常量:

常量名 描述
PI 3.14159 圆周率
E 2.71828 自然对数的底
GRAVITY 9.81 重力加速度

访问模块常量

1
2
3
4
5
6
7
-- 导入模块
local math_module = require("mymodule")

-- 访问模块常量
print("PI:", math_module.PI)
print("E:", math_module.E)
print("GRAVITY:", math_module.GRAVITY)

3. 模块函数

3.1 几何计算

计算圆的面积

1
2
3
4
5
6
function mymodule.circle_area(radius)
-- 计算圆的面积
-- 参数: radius - 圆的半径(非负数)
-- 返回值: 圆的面积
-- 错误: 如果半径无效(不是数字或为负数),抛出错误
end

示例

1
2
3
local circle_radius = 5
local circle_area = math_module.circle_area(circle_radius)
print("Circle area with radius " .. circle_radius .. ":", circle_area)

计算矩形的面积

1
2
3
4
5
6
7
function mymodule.rectangle_area(width, height)
-- 计算矩形的面积
-- 参数: width - 矩形的宽度(非负数)
-- height - 矩形的高度(非负数)
-- 返回值: 矩形的面积
-- 错误: 如果参数无效(不是数字或为负数),抛出错误
end

示例

1
2
3
local rect_width, rect_height = 4, 6
local rect_area = math_module.rectangle_area(rect_width, rect_height)
print("Rectangle area (" .. rect_width .. "x" .. rect_height .. "):", rect_area)

计算三角形的面积

1
2
3
4
5
6
7
function mymodule.triangle_area(base, height)
-- 计算三角形的面积
-- 参数: base - 三角形的底(非负数)
-- height - 三角形的高(非负数)
-- 返回值: 三角形的面积
-- 错误: 如果参数无效(不是数字或为负数),抛出错误
end

示例

1
2
3
local tri_base, tri_height = 3, 7
local tri_area = math_module.triangle_area(tri_base, tri_height)
print("Triangle area (base=" .. tri_base .. ", height=" .. tri_height .. "):", tri_area)

3.2 数学函数

计算阶乘

1
2
3
4
5
6
function mymodule.factorial(n)
-- 计算阶乘
-- 参数: n - 非负整数
-- 返回值: n的阶乘
-- 错误: 如果参数无效(不是数字或为负数),抛出错误
end

示例

1
2
3
local fact_num = 5
local fact_result = math_module.factorial(fact_num)
print("Factorial of " .. fact_num .. ":", fact_result)

3.3 素数判断

1
2
3
4
5
6
function mymodule.is_prime(n)
-- 判断是否为素数
-- 参数: n - 整数
-- 返回值: 如果n是素数,返回true;否则返回false
-- 错误: 如果参数不是数字,抛出错误
end

示例

1
2
3
4
5
local test_nums = {2, 3, 4, 17, 20, 23, 100}
for _, num in ipairs(test_nums) do
local is_prime = math_module.is_prime(num)
print(num .. " is prime?", is_prime)
end

3.4 斐波那契数列

1
2
3
4
5
6
7
function mymodule.fibonacci(n)
-- 生成斐波那契数列
-- 参数: n - 数列长度(正整数)
-- 返回值: 包含前n个斐波那契数的表
-- 错误: 如果参数不是数字,抛出错误
-- 注意: 如果n <= 0,返回空表
end

示例

1
2
3
local fib_count = 10
local fib_sequence = math_module.fibonacci(fib_count)
print("First " .. fib_count .. " Fibonacci numbers:", table.concat(fib_sequence, ", "))

3.5 最大公约数和最小公倍数

计算最大公约数

1
2
3
4
5
6
function mymodule.gcd(a, b)
-- 计算两个数的最大公约数
-- 参数: a, b - 两个整数
-- 返回值: a和b的最大公约数
-- 错误: 如果参数不是数字,抛出错误
end

示例

1
2
3
local a, b = 24, 36
local gcd_result = math_module.gcd(a, b)
print("GCD of " .. a .. " and " .. b .. ":", gcd_result)

计算最小公倍数

1
2
3
4
5
6
7
function mymodule.lcm(a, b)
-- 计算两个数的最小公倍数
-- 参数: a, b - 两个整数
-- 返回值: a和b的最小公倍数
-- 错误: 如果参数不是数字,抛出错误
-- 注意: 如果a或b为0,返回0
end

示例

1
2
3
local a, b = 24, 36
local lcm_result = math_module.lcm(a, b)
print("LCM of " .. a .. " and " .. b .. ":", lcm_result)

3.6 角度和弧度转换

将角度转换为弧度

1
2
3
4
5
6
function mymodule.deg_to_rad(degrees)
-- 将角度转换为弧度
-- 参数: degrees - 角度值
-- 返回值: 对应的弧度值
-- 错误: 如果参数不是数字,抛出错误
end

示例

1
2
3
local degrees = 90
local radians = math_module.deg_to_rad(degrees)
print(degrees .. " degrees = ", radians, " radians")

将弧度转换为角度

1
2
3
4
5
6
function mymodule.rad_to_deg(radians)
-- 将弧度转换为角度
-- 参数: radians - 弧度值
-- 返回值: 对应的角度值
-- 错误: 如果参数不是数字,抛出错误
end

示例

1
2
3
local radians_val = math_module.PI / 2
local degrees_val = math_module.rad_to_deg(radians_val)
print(radians_val .. " radians = ", degrees_val, " degrees")

4. 模块的导入和使用

4.1 完整导入

最简单的方法是完整导入整个模块,这样可以访问模块的所有常量和函数。

1
2
3
4
5
6
7
8
9
-- 导入模块
local math_module = require("mymodule")

-- 使用模块常量
print("PI:", math_module.PI)

-- 使用模块函数
local area = math_module.circle_area(5)
print("Circle area:", area)

4.2 选择性导入常用函数

如果只需要使用模块中的部分函数,可以选择性地导入这些函数,这样可以减少代码中的重复前缀。

1
2
3
4
5
6
7
8
9
-- 导入模块
local math_module = require("mymodule")

-- 选择性导入常用函数
local is_prime, factorial = math_module.is_prime, math_module.factorial

-- 直接使用导入的函数
print("is_prime(17):", is_prime(17))
print("factorial(6):", factorial(6))

4.3 重命名导入的模块

如果觉得模块名称太长,可以在导入时给模块指定一个简短的别名。

1
2
3
4
5
6
-- 重命名导入的模块
local mm = require("mymodule")

-- 使用别名访问模块的常量和函数
print("mm.PI:", mm.PI)
print("mm.circle_area(3):", mm.circle_area(3))

5. 模块函数的错误处理

mymodule 模块中的函数会对输入参数进行验证,如果参数无效,会抛出错误。为了避免程序因为错误而终止,应该使用 pcall 函数来捕获和处理这些错误。

基本错误处理

1
2
3
4
5
6
7
-- 使用pcall捕获错误
local success, result = pcall(math_module.circle_area, -5)
if not success then
print("Error caught:", result)
else
print("Circle area:", result)
end

批量测试错误情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 测试多个错误情况
local test_cases = {
{func = math_module.rectangle_area, args = {"invalid", 5}, desc = "Invalid width (string)"},
{func = math_module.triangle_area, args = {3, -2}, desc = "Negative height"},
{func = math_module.factorial, args = {-1}, desc = "Negative factorial"}
}

for _, case in ipairs(test_cases) do
local success, err = pcall(case.func, unpack(case.args))
if not success then
print(case.desc .. " error:", err)
else
print(case.desc .. " result:", err)
end
end

6. 模块的扩展

在 Lua 中,可以在导入模块后为其添加新的函数或修改现有的函数,这种扩展只在当前 Lua 环境中有效,不会修改原始模块文件。

添加新函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- 导入模块
local math_module = require("mymodule")

-- 添加新函数:计算正方形的面积
function math_module.quadratic_area(side)
-- 验证参数
if type(side) ~= "number" or side < 0 then
error("Invalid side: must be a non-negative number")
end
return side * side
end

-- 使用新函数
local square_side = 4
local square_area = math_module.quadratic_area(square_side)
print("Square area with side " .. square_side .. ":", square_area)

修改现有函数

1
2
3
4
5
6
7
8
9
10
11
12
-- 保存原始函数
local original_circle_area = math_module.circle_area

-- 修改函数:添加日志输出
function math_module.circle_area(radius)
print("Calculating circle area with radius:", radius)
return original_circle_area(radius)
end

-- 使用修改后的函数
local area = math_module.circle_area(5)
print("Circle area:", area)

7. 模块的缓存机制

Lua 会缓存已导入的模块,多次 require 同一个模块只会返回同一个实例,不会重复加载模块文件。

1
2
3
4
5
6
7
8
-- 第一次导入模块
local module1 = require("mymodule")

-- 第二次导入同一模块(返回缓存的实例)
local module2 = require("mymodule")

-- 验证两个变量引用的是同一个实例
print("Are module1 and module2 the same instance?", module1 == module2) -- 输出: true

缓存机制的影响

  1. 优点:提高性能,避免重复加载和初始化模块
  2. 注意:如果在运行时修改了模块,所有引用该模块的地方都会受到影响

8. 示例代码

完整示例:使用 mymodule 模块进行各种计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
-- Lua模块使用示例
-- print语句使用英语,注释使用中文

print("=== Lua Module Usage Example ===")

-- 1. 导入模块
print("\n1. Importing Module")
local math_module = require("mymodule")

-- 2. 访问模块常量
print("\n2. Accessing Module Constants")
print("PI:", math_module.PI)
print("E:", math_module.E)
print("GRAVITY:", math_module.GRAVITY)

-- 3. 调用模块函数
print("\n3. Calling Module Functions")

-- 3.1 几何计算
print("\n3.1 Geometric Calculations")
local circle_radius = 5
local circle_area = math_module.circle_area(circle_radius)
print("Circle area with radius " .. circle_radius .. ":", circle_area)

local rect_width, rect_height = 4, 6
local rect_area = math_module.rectangle_area(rect_width, rect_height)
print("Rectangle area (" .. rect_width .. "x" .. rect_height .. "):", rect_area)

local tri_base, tri_height = 3, 7
local tri_area = math_module.triangle_area(tri_base, tri_height)
print("Triangle area (base=" .. tri_base .. ", height=" .. tri_height .. "):", tri_area)

-- 3.2 数学函数
print("\n3.2 Mathematical Functions")
local fact_num = 5
local fact_result = math_module.factorial(fact_num)
print("Factorial of " .. fact_num .. ":", fact_result)

-- 3.3 素数判断
print("\n3.3 Prime Number Check")
local test_nums = {2, 3, 4, 17, 20, 23, 100}
for _, num in ipairs(test_nums) do
local is_prime = math_module.is_prime(num)
print(num .. " is prime?", is_prime)
end

-- 3.4 斐波那契数列
print("\n3.4 Fibonacci Sequence")
local fib_count = 10
local fib_sequence = math_module.fibonacci(fib_count)
print("First " .. fib_count .. " Fibonacci numbers:", table.concat(fib_sequence, ", "))

-- 3.5 最大公约数和最小公倍数
print("\n3.5 Greatest Common Divisor and Least Common Multiple")
local a, b = 24, 36
local gcd_result = math_module.gcd(a, b)
local lcm_result = math_module.lcm(a, b)
print("GCD of " .. a .. " and " .. b .. ":", gcd_result)
print("LCM of " .. a .. " and " .. b .. ":", lcm_result)

-- 3.6 角度和弧度转换
print("\n3.6 Degree and Radian Conversion")
local degrees = 90
local radians = math_module.deg_to_rad(degrees)
print(degrees .. " degrees = ", radians, " radians")

local radians_val = math_module.PI / 2
local degrees_val = math_module.rad_to_deg(radians_val)
print(radians_val .. " radians = ", degrees_val, " degrees")

-- 4. 不同的模块导入方式
print("\n4. Different Module Import Methods")

-- 4.1 完整导入(已演示)
-- local math_module = require("mymodule")

-- 4.2 选择性导入常用函数
print("\n4.2 Selective Function Import")
local is_prime, factorial = math_module.is_prime, math_module.factorial
print("Using selectively imported functions:")
print("is_prime(17):", is_prime(17))
print("factorial(6):", factorial(6))

-- 4.3 重命名导入的模块
print("\n4.3 Renaming Imported Module")
local mm = require("mymodule") -- 简短别名
print("Using renamed module (mm):")
print("mm.PI:", mm.PI)
print("mm.circle_area(3):", mm.circle_area(3))

-- 5. 模块函数的错误处理
print("\n5. Error Handling in Module Functions")

-- 使用pcall捕获错误
local success, result = pcall(math_module.circle_area, -5)
if not success then
print("Error caught:", result)
end

-- 测试其他错误情况
local test_cases = {
{func = math_module.rectangle_area, args = {"invalid", 5}, desc = "Invalid width (string)"},
{func = math_module.triangle_area, args = {3, -2}, desc = "Negative height"},
{func = math_module.factorial, args = {-1}, desc = "Negative factorial"}
}

for _, case in ipairs(test_cases) do
local success, err = pcall(case.func, unpack(case.args))
if not success then
print(case.desc .. " error:", err)
end
end

-- 6. 多次导入同一模块
print("\n6. Multiple Imports of the Same Module")
-- Lua会缓存已导入的模块,多次require只会返回同一个实例
local module1 = require("mymodule")
local module2 = require("mymodule")

print("Are module1 and module2 the same instance?", module1 == module2)

-- 7. 模块的扩展(在使用处添加新函数)
print("\n7. Module Extension")
-- 可以在导入后为模块添加新函数
function math_module.quadratic_area(side)
return side * side
end

local square_side = 4
local square_area = math_module.quadratic_area(square_side)
print("Square area with side " .. square_side .. ":", square_area)

-- 注意:这种扩展只在当前 Lua 环境中有效,不会修改原始模块文件

print("\n=== End of Module Usage Example ===")

9. 最佳实践

  1. 错误处理:始终使用 pcall 捕获模块函数可能抛出的错误
  2. 模块导入:根据需要选择合适的导入方式(完整导入、选择性导入或重命名导入)
  3. 参数验证:在调用模块函数前,确保提供有效的参数
  4. 模块扩展:谨慎扩展或修改模块,因为这些修改会影响所有引用该模块的代码
  5. 代码组织:将相关功能组织到模块中,提高代码的可维护性和可重用性

性能优化建议

  1. 避免重复导入:在文件顶部导入模块一次,然后在整个文件中使用
  2. 选择性导入:对于频繁使用的函数,考虑选择性导入以减少代码量
  3. 缓存模块实例:如果在多个地方使用同一模块,缓存模块实例以避免重复查找

总结

mymodule 是一个功能丰富的数学工具模块,提供了多种数学计算功能,包括几何计算、数学函数、素数判断、斐波那契数列生成、最大公约数和最小公倍数计算、角度和弧度转换等。

通过本教程的学习,您应该已经掌握了 mymodule 模块的使用方法,包括:

  • 如何导入和使用模块
  • 如何访问模块的常量和函数
  • 如何处理模块函数可能抛出的错误
  • 如何扩展模块功能
  • 模块的缓存机制及其影响

模块是 Lua 中组织代码的重要方式,合理使用模块可以提高代码的可维护性、可重用性和可读性。希望本教程对您有所帮助!

mymodule.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
-- Lua模块示例
-- print语句使用英语,注释使用中文

-- 定义一个数学工具模块
local mymodule = {}

-- 模块常量
mymodule.PI = 3.14159
mymodule.E = 2.71828
mymodule.GRAVITY = 9.81

-- 模块私有函数(以下划线开头表示私有)
local function _validate_number(num)
return type(num) == "number" and num == num -- 检查是否为有效数字(排除NaN)
end

-- 模块函数:计算圆的面积
function mymodule.circle_area(radius)
if not _validate_number(radius) or radius < 0 then
error("Invalid radius: must be a non-negative number")
end
return mymodule.PI * radius * radius
end

-- 模块函数:计算矩形的面积
function mymodule.rectangle_area(width, height)
if not _validate_number(width) or not _validate_number(height) then
error("Invalid dimensions: must be numbers")
end
if width < 0 or height < 0 then
error("Invalid dimensions: must be non-negative")
end
return width * height
end

-- 模块函数:计算三角形的面积
function mymodule.triangle_area(base, height)
if not _validate_number(base) or not _validate_number(height) then
error("Invalid dimensions: must be numbers")
end
if base < 0 or height < 0 then
error("Invalid dimensions: must be non-negative")
end
return 0.5 * base * height
end

-- 模块函数:计算阶乘
function mymodule.factorial(n)
if not _validate_number(n) then
error("Invalid input: must be a number")
end
if n < 0 then
error("Invalid input: must be non-negative")
end
if n == 0 or n == 1 then
return 1
end
local result = 1
for i = 2, n do
result = result * i
end
return result
end

-- 模块函数:判断是否为素数
function mymodule.is_prime(n)
if not _validate_number(n) then
error("Invalid input: must be a number")
end
if n <= 1 then
return false
end
if n <= 3 then
return true
end
if n % 2 == 0 or n % 3 == 0 then
return false
end
local i = 5
while i * i <= n do
if n % i == 0 or n % (i + 2) == 0 then
return false
end
i = i + 6
end
return true
end

-- 模块函数:生成斐波那契数列
function mymodule.fibonacci(n)
if not _validate_number(n) then
error("Invalid input: must be a number")
end
if n <= 0 then
return {}
end
local fib = {1}
if n > 1 then
table.insert(fib, 1)
for i = 3, n do
table.insert(fib, fib[i-1] + fib[i-2])
end
end
return fib
end

-- 模块函数:计算两个数的最大公约数
function mymodule.gcd(a, b)
if not _validate_number(a) or not _validate_number(b) then
error("Invalid input: must be numbers")
end
a = math.abs(a)
b = math.abs(b)
while b ~= 0 do
a, b = b, a % b
end
return a
end

-- 模块函数:计算两个数的最小公倍数
function mymodule.lcm(a, b)
if not _validate_number(a) or not _validate_number(b) then
error("Invalid input: must be numbers")
end
if a == 0 or b == 0 then
return 0
end
return math.abs(a * b) / mymodule.gcd(a, b)
end

-- 模块函数:将角度转换为弧度
function mymodule.deg_to_rad(degrees)
if not _validate_number(degrees) then
error("Invalid input: must be a number")
end
return degrees * mymodule.PI / 180
end

-- 模块函数:将弧度转换为角度
function mymodule.rad_to_deg(radians)
if not _validate_number(radians) then
error("Invalid input: must be a number")
end
return radians * 180 / mymodule.PI
end

-- 返回模块表
return mymodule

module_example.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
-- Lua模块使用示例
-- print语句使用英语,注释使用中文

print("=== Lua Module Usage Example ===")

-- 1. 导入模块
print("\n1. Importing Module")
local math_module = require("mymodule")

-- 2. 访问模块常量
print("\n2. Accessing Module Constants")
print("PI:", math_module.PI)
print("E:", math_module.E)
print("GRAVITY:", math_module.GRAVITY)

-- 3. 调用模块函数
print("\n3. Calling Module Functions")

-- 3.1 几何计算
print("\n3.1 Geometric Calculations")
local circle_radius = 5
local circle_area = math_module.circle_area(circle_radius)
print("Circle area with radius " .. circle_radius .. ":", circle_area)

local rect_width, rect_height = 4, 6
local rect_area = math_module.rectangle_area(rect_width, rect_height)
print("Rectangle area (" .. rect_width .. "x" .. rect_height .. "):", rect_area)

local tri_base, tri_height = 3, 7
local tri_area = math_module.triangle_area(tri_base, tri_height)
print("Triangle area (base=" .. tri_base .. ", height=" .. tri_height .. "):", tri_area)

-- 3.2 数学函数
print("\n3.2 Mathematical Functions")
local fact_num = 5
local fact_result = math_module.factorial(fact_num)
print("Factorial of " .. fact_num .. ":", fact_result)

-- 3.3 素数判断
print("\n3.3 Prime Number Check")
local test_nums = {2, 3, 4, 17, 20, 23, 100}
for _, num in ipairs(test_nums) do
local is_prime = math_module.is_prime(num)
print(num .. " is prime?", is_prime)
end

-- 3.4 斐波那契数列
print("\n3.4 Fibonacci Sequence")
local fib_count = 10
local fib_sequence = math_module.fibonacci(fib_count)
print("First " .. fib_count .. " Fibonacci numbers:", table.concat(fib_sequence, ", "))

-- 3.5 最大公约数和最小公倍数
print("\n3.5 Greatest Common Divisor and Least Common Multiple")
local a, b = 24, 36
local gcd_result = math_module.gcd(a, b)
local lcm_result = math_module.lcm(a, b)
print("GCD of " .. a .. " and " .. b .. ":", gcd_result)
print("LCM of " .. a .. " and " .. b .. ":", lcm_result)

-- 3.6 角度和弧度转换
print("\n3.6 Degree and Radian Conversion")
local degrees = 90
local radians = math_module.deg_to_rad(degrees)
print(degrees .. " degrees = ", radians, " radians")

local radians_val = math_module.PI / 2
local degrees_val = math_module.rad_to_deg(radians_val)
print(radians_val .. " radians = ", degrees_val, " degrees")

-- 4. 不同的模块导入方式
print("\n4. Different Module Import Methods")

-- 4.1 完整导入(已演示)
-- local math_module = require("mymodule")

-- 4.2 选择性导入常用函数
print("\n4.2 Selective Function Import")
local is_prime, factorial = math_module.is_prime, math_module.factorial
print("Using selectively imported functions:")
print("is_prime(17):", is_prime(17))
print("factorial(6):", factorial(6))

-- 4.3 重命名导入的模块
print("\n4.3 Renaming Imported Module")
local mm = require("mymodule") -- 简短别名
print("Using renamed module (mm):")
print("mm.PI:", mm.PI)
print("mm.circle_area(3):", mm.circle_area(3))

-- 5. 模块函数的错误处理
print("\n5. Error Handling in Module Functions")

-- 使用pcall捕获错误
local success, result = pcall(math_module.circle_area, -5)
if not success then
print("Error caught:", result)
end

-- 测试其他错误情况
local test_cases = {
{func = math_module.rectangle_area, args = {"invalid", 5}, desc = "Invalid width (string)"},
{func = math_module.triangle_area, args = {3, -2}, desc = "Negative height"},
{func = math_module.factorial, args = {-1}, desc = "Negative factorial"}
}

for _, case in ipairs(test_cases) do
local success, err = pcall(case.func, unpack(case.args))
if not success then
print(case.desc .. " error:", err)
end
end

-- 6. 多次导入同一模块
print("\n6. Multiple Imports of the Same Module")
-- Lua会缓存已导入的模块,多次require只会返回同一个实例
local module1 = require("mymodule")
local module2 = require("mymodule")

print("Are module1 and module2 the same instance?", module1 == module2)

-- 7. 模块的扩展(在使用处添加新函数)
print("\n7. Module Extension")
-- 可以在导入后为模块添加新函数
function math_module.quadratic_area(side)
return side * side
end

local square_side = 4
local square_area = math_module.quadratic_area(square_side)
print("Square area with side " .. square_side .. ":", square_area)

-- 注意:这种扩展只在当前 Lua 环境中有效,不会修改原始模块文件

print("\n=== End of Module Usage Example ===")