Thử viết shell script theo dạng hướng đối tượng
Bài đăng này đã không được cập nhật trong 8 năm
Bài viết được dịch từ nguồn http://hipersayanx.blogspot.com/2012/12/object-oriented-programming-in-bash.html
Bash rất phổ biến và đó là ngôn ngữ lập trình tập trung vào việc thực hiện lệnh. Lập trình hướng đối tượng (OOP) là một mô hình lập trình hướng tới một đối tượng với một tập các thuộc tính và hành động mà nó có thể thực hiện. Nếu bạn sử dụng Bash để viết các chương trình đơn giản và ngắn, lập trình thủ tục thì bạn không cần nhiều hơn. Nhưng nếu chương trình của bạn ngày càng trở nên lớn hơn, một chương trình to lớn (> 1000 dòng), thì bạn cần một cách tốt hơn để cấu trúc chương trình của bạn để giúp duy trì và đọc dễ dàng. Tất nhiên, Bash thiếu các tính năng OOP, nhưng với một số thủ thuật bạn có thể mô phỏng nó với một vài dòng được thêm vào, và tôi sẽ chỉ cho bạn làm thế nào.
Chú ý: Bạn cần có khái niệm vững chắc về OOP và Bash trước khi đọc, tôi sẽ không giải thích điều này ở đây.
Đầu tiên tạo ra một chương trình mà trong đó bạn sẽ xác định lớp đối tượng của bạn, và cho phép nó thực hiện các method.
touch vector.sh
chmod +x vector.sh
Sau đó sao chép đoạn code sau:
#!/bin/bash
# Base class. (1)
function Vector()
{
# A pointer to this Class. (2)
base=$FUNCNAME
this=$1
# Inherited classes (optional). (3)
export ${this}_inherits="Class1 Class2 Class3" # (3.1)
for class in $(eval "echo \$${this}_inherits")
do
for property in $(compgen -A variable ${class}_)
do
export ${property/#$class\_/$this\_}="${property}" # (3.2)
done
for method in $(compgen -A function ${class}_)
do
export ${method/#$class\_/$this\_}="${method} ${this}"
done
done
# Declare Properties. (4)
export ${this}_x=$2
export ${this}_y=$3
export ${this}_z=$4
# Declare methods. (5)
for method in $(compgen -A function)
do
export ${method/#$base\_/$this\_}="${method} ${this}"
done
}
# Human readable representation of the vector. (6)
function Vector_show()
{
# (7)
base=$(expr "$FUNCNAME" : '\([a-zA-Z][a-zA-Z0-9]*\)')
this=$1
x=$(eval "echo \$${this}_x")
y=$(eval "echo \$${this}_y")
z=$(eval "echo \$${this}_z")
echo "$this ($x, $y, $z)"
}
# Adds two vectors.
function Vector_add()
{
base=$(expr "$FUNCNAME" : '\([a-zA-Z][a-zA-Z0-9]*\)')
this=$1
other=$2
# Get it's components
x1=$(eval "echo \$${this}_x")
y1=$(eval "echo \$${this}_y")
z1=$(eval "echo \$${this}_z")
x2=$(eval "echo \$${other}_x")
y2=$(eval "echo \$${other}_y")
z2=$(eval "echo \$${other}_z")
# Add it's components
x=$(($x1 + $x2))
y=$(($y1 + $y2))
z=$(($z1 + $z2))
# Create a new vector. (8)
Vector 'vector3' $x $y $z
$vector3_show
}
-
Đây hàm của một
class. Nó phải có cùng tên củaclass. Tên của mộtclasskhông thể chứa dấu gạch dưới (_). Chúng ta sẽ sử dụng hàm này để tạo cácmethodcủa lớp "Vector". -
Ở đây bạn có thể có được một
base classcủa đối tượng và một tham chiếu của đối tượng được tạo ra. Đối số đầu tiên của hàm tạo phải luôn là tên của đối tượng để tạo ra. -
Khối
codenày mô phỏng thừa kế, bạn có thể gỡ bỏ nó nếu bạn không cần. 3.1. Mỗi thuộc tính và phương thức của lớp có thể được gọi như$ {this} _methodProperty_name, hoặc bạn cũng có thể gọi nó là lớp cơ sở như$ {base} _methodProperty_name. Nhiềuclassthừa kếoveridecác phương thức và thuộc tính (m & p) của cácclasstrước như sau: 3.2. Điều này sẽexportm & p củabase classnhư m & p củaclass. -
Mỗi phương thức và thuộc tính của lớp được xuất ra như là một biến
globaldưới dạngobjectName_methodProperty_name. Bạn có thể khởi tạo các thuộc tính thông qua các tham số, hoặc với một giá trị mặc định, hoặc để nó không bắt buộc. -
Điều này sẽ tìm thấy tất cả các
functionvớiprefixlàBaseClass_ *và tạo nó như là một biếnglobalthay thếBaseClassvới tên của đối tượng, giá trị của biến sẽ là một chuỗi vớifunctionlớp cơ sở và tênclasslà tham số đầu tiên đóng vai trò là một tham chiếu Với nó. -
Các
functioncủa lớp được định nghĩa làBaseClass_methodName. Tênfunctioncó thể chứa dấu gạch dưới,camelCaseđược khuyến khích. -
Lấy một tham chiếu đến
base class(không bắt buộc) và đối tượng, đối số đầu tiên là tên đối tượng. -
Tất nhiên, bạn có thể tạo các đối tượng mới bên trong các
functioncủa cùng một lớp.
Để sử dụng các class. Tạo một phần mềm từ đó bạn sẽ sử dụng class mà bạn đã định nghĩa:
#!/bin/bash
# Import the class definition file.
. vector.sh
function main()
{
# Create the vectors objects. (1)
Vector 'vector1' 1 2 3
Vector 'vector2' 7 5 3
# Show it's properties. (2)
echo "vector1 ($vector1_x, $vector1_y, $vector1_z)"
echo "vector2 ($vector2_x, $vector2_y, $vector2_z)"
# Call to it's methods.
$vector1_show
$vector2_show
$vector1_add vector2
}
main
1.Các đối tượng được khai báo là đối tượng class objectName [arg1 arg2 arg3 ...].
2.Bây giờ bạn có thể gọi các function và thuộc tính như $ objectName_methodsProperty_name [arg1 arg2 arg3 ...].
Kết qủa là:
$ ./main.sh
vector1 (1, 2, 3)
vector2 (7, 5, 3)
vector1 (1, 2, 3)
vector2 (7, 5, 3)
vector3 (8, 7, 6)
OOP trong Bash đã được tạo. Thành tựu đạt được: D (OOP in Bash unlocked. Achievement reached
)
Cảm ơn và hi vọng bài viết có ích cho công việc của bạn.
All rights reserved