Tải bản đầy đủ (.pdf) (354 trang)

Học lập trình ngôn ngữ Perl

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.01 MB, 354 trang )








Học
Perl



Randal L. Schwartz

Người dịch: Ngô Trung Việt






Hà Nội 5/1999







Learning
Perl





Randal L. Schwartz









O’Reilly & Associates, Inc., 1993



i


Mục lục



1 Giới thiệu 1
Lịch sử Perl 1
Mục đích của Perl 3
Tính sẵn có 3
Hỗ trợ 5
Các khái niệm cơ bản 6

Dạo qua Perl 9
Chương trình “Xin chào mọi người” 10
Hỏi câu hỏi và nhớ kết quả 11
Bổ sung chọn lựa 12
Đoán từ bí mật 13
Nhiều từ bí mật 14
Cho mỗi người một từ bí mật khác nhau 16
Giải quyết dạng thức cái vào thay đổi 19
Làm cho công bằng với mọi người 21
Làm cho nó mô đun hơn một chút 24
Chuyển danh sách từ bí mật vào tệp riêng biệt 28
Đảm bảo một lượng an toàn giản dị 33
Cảnh báo ai đó khi mọi việc đi sai 34
Nhiều tệp từ bí mật trong danh mục hiện tại 36
Nhưng chúng ta biết họ là ai! 38
Liệt kê các từ bí mật 40



ii
Làm cho danh sách từ cũ đó đáng lưu ý hơn 44
Duy trì cơ sở dữ liệu đoán đúng cuối cùng 45
Chương trình cuối cùng 48
Bài tập 51
2 Dữ liệu vô hướng 53
Dữ liệu vô hướng là gì? 53
Số 54
Tất cả các số đã có cùng dạng thức bên trong 54
Hằng kí hiệu động 54
Hằng kí hiệu nguyên 55

Xâu 56
Xâu dấu nháy đơn 56
Xâu dấu nháy kép 57
Toán tử 59
Toán tử số 59
Toán tử xâu 61
Thứ tự ưu tiên và luật kết hợp của toán tử 63
Chuyển đổi giữa số và xâu 66
Các toán tử trên biến vô hướng 68
Toán tử gán hai ngôi 69
Tự tăng và tự giảm 71
Toán tử chop() 72
Xen lẫn vô hướng vào trong xâu 73
<STDIN> xem như một vô hướng 75
Đưa ra bằng print() 76
Giá trị undef 77
Bài tập 78
3 Dữ liệu mảng và danh sách 79



iii
Mảng là gì? 79
Biểu diễn hằng kí hiệu 80
Biến 81
Toán tử 82
Phép gán 82
Truy nhập phần tử 85
Các toán tử push() và pop() 88
Các toán tử shift() và unshift() 89

Toán tử reverse() 89
Toán tử sort() 90
Toán tử chop() 90
Hoàn cảnh vô hướng và mảng 91
<STDIN> như một mảng 92
Xen lẫn biến mảng 92
Bài tập 94
4 Cấu trúc điều khiển 97
Khối câu lệnh 97
Câu lệnh if/unless 98
Câu lệnh while/until 101
Câu lệnh for 103
Câu lệnh foreach 104
Bài tập 106
5 Mảng kết hợp 109
Mảng kết hợp là gì? 109
Biến mảng kết hợp 110
Biểu diễn hằng kí hiệu cho mảng kết hợp 111
Các toán tử mảng kết hợp 112



iv
Toán tử keys() 112
Toán tử values() 113
Toán tử each() 114
Toán tử delete 114
Bài tập 115
6 Vào / ra cơ bản 117
Vào từ STDIN 117

Đưa vào từ toán tử hình thoi 119
Đưa ra STDOUT 120
Dùng print cho đưa ra thông thường 120
Dùng printf cho cái ra có dạng thức 121
Bài tập 122
7 Biểu thức chính qui 123
Khái niệm về biểu thức chính qui 123
Cách dùng đơn giản về biểu thức chính qui 124
Khuôn mẫu 126
Khuôn mẫu một kí tự 127
Khuôn mẫu nhóm 129
Dấu ngoặc tròn như bộ nhớ 132
Thay phiên 134
Khuôn mẫu neo 134
Thứ tự ưu tiên 136
Thêm về toán tử đối sánh 137
Chọn một mục tiêu khác (toán tử =~) 137
Bỏ qua chữ hoa thường 138
Dùng một định biên khác 139



v
Dùng xen lẫn biến 140
Biến chỉ đọc đặc biệt 141
Thay thế 142
Các toán tử split() và join() 144
Toán tử split() 144
Toán tử join() 146
Bài tập 146

8 Hàm 149
Hàm hệ thống và hàm người dùng 149
Xác định một hàm người dùng 149
Gọi một hàm người dùng 151
Giá trị cho lại 152
Đối 153
Biến cục bộ trong hàm 156
Bài tập 159
9 Các cấu trúc điều khiển khác 161
Toán tử last 161
Toán tử next 163
Toán tử redo 164
Khối có nhãn 165
Bộ thay đổi biểu thức 167
&&, || và ?: xem như các cấu trúc điều khiển 169
Bài tập 171
10 Tước hiệu tệp và kiểm thử tệp 173
Tước hiệu tệp là gì? 173



vi
Mở và đóng một tước hiệu tệp 174
Một chút tiêu khiển: die() 175
Dùng tước hiệu tệp 177
Kiểm tra tệp -x 178
Các toán tử stat() và lstat() 183
Dùng _Filehandle 184
Bài tập 185
11 Dạng thức 187

Dạng thức là gì? 187
Định nghĩa một dạng thức 188
Gọi một dạng thức 191
Nói thêm về nơi giữ tệp 193
Trường văn bản 194
Trường số 194
Trường nhiều dòng 196
Trường được lấp đầy 196
Dạng thức đầu trang 200
Thay đổi mặc định cho dạng thức 201
Dùng select() để thay đổi tước hiệu tệp 201
Thay đổi tên dạng thức 203
Đổi tên dạng thức đầu trang 204
Đổi chiều dài trang 205
Thay đổi vị trí trên trang 206
Bài tập 207
12 Truy nhập danh mục 209
Chuyển vòng quanh cây danh mục 209
Globbing 210



vii
Tước hiệu danh mục 213
Mở và đóng tước hiệu danh mục 214
Đọc một tước hiệu danh mục 215
Bài tập 216
13 Thao tác tệp và danh mục 217
Loại bỏ tệp 217
Đổi tên tệp 219

Tạo ra tên thay phiên cho một tệp (móc nối) 220
Về móc nối cứng và mềm 220
Tạo ra các móc nối cứng và mềm bằng Perl 222
Tạo ra và xoá danh mục 224
Thay đổi phép sử dụng 225
Thay đổi quyền sở hữu 226
Thay đổi nhãn thời gian 227
Bài tập 229
14 Quản lí tiến trình 230
Dùng system() và exec() 230
Dùng dấu nháy đơn ngược 235
Dùng các tiến trình như tước hiệu tệp 236
Dùng fork 238
Tóm tắt về các phép toán tiến trình 241
Gửi và nhận tín hiệu 243
Bài tập 246
15 Biến đổi dữ liệu khác 249
Tìm một xâu con 249
Trích và thay thế một xâu con 251



viii
Dạng thức dữ liệu bằng sprintf() 254
Sắp xếp nâng cao 254
Chuyển tự 260
Bài tập 263
16 Truy nhập cơ sở dữ liệu hệ thống 265
Lấy mật hiệu và thông tin nhóm 265
Gói và mở dữ liệu nhị phân 270

Lấy thông tin mạng 273
Lấy các thông tin khác 275
Bài tập 276
17 Thao tác cơ sở dữ liệu người dùng 277
Cơ sở dữ liệu DBM và mảng DBM 277
Mở và đóng mảng DBM 278
Dùng mảng DBM 280
Cơ sở dữ liệu truy nhập ngẫu nhiên chiều dài cố
định 281
Cơ sở dữ liệu (văn bản) chiều dài thay đổi 284
Bài tập 287
18 Chuyển đổi các ngôn ngữ khác sang Perl 289
Chuyển chương trình awk sang Perl 289
Chuyển đổi chương trình sed sang Perl 291
Chuyển đổi chương trình Shell sang Perl 292
Bài tập 293
Phụ lục A Trả lời các bài tập 295



ix
Chương 2, Dữ liệu vô hướng 295
Chương 3, Mảng và dữ liệu danh sách 297
Chương 4, Cấu trúc điều khiển 299
Chương 5, Mảng kết hợp 302
Chương 6, Vào/ra cơ sở 305
Chương 7, Biểu thức chính qui 307
Chương 8, Hàm 311
Chương 9, Các cấu trúc điều khiển khác 314
Chương 10, Tước hiệu tệp và kiểm thử tệp 315

Chương 11, Dạng thức 317
Chương 12, Truy nhập danh mục 319
Chương 13, Thao tác tệp và danh mục 320
Chương 14, Quản lí tiến trình 323
Chương 15, Biến đổi dữ liệu khác 326
Chương 16, Truy nhập cơ sở dữ liệu hệ thống 329
Chương 17, Thao tác cơ sở dữ liệu người dùng 330
Chương 18, Chuyển các ngôn ngữ khác sang Perl
332
Phụ lục B Cơ sở về nối mạng 333
Mô hình khe cắm 333
Một khách mẫu 335
Bộ phục vụ mẫu 335
Phụ lục C Các chủ đề còn chưa nói tới 337
Trình gỡ lỗi 337
Dòng lệnh 338
Các toán tử khác 338
Nhiều, nhiều hàm nữa 338
Nhiều, nhiều biến định nghĩa sẵn 338
Xâu ở đây 338
Trở về (từ trình con) 339



x
Toán tử eval (và s///e) 339
Thao tác bảng kí hiệu bằng *FRED 340
Toán tử goto 340
Toán tử require 341
Thư viện 341

Tin vui về Perl 5.0 341








1

1


Giới thiệu



Lịch sử Perl
Perl là cách viết tắt cho “Practical Extraction and
Report Language” Ngôn ngữ báo cáo và trích rút thực
hành, mặc dầu nó cũng còn được gọi là “Pathologically
Eclectic Rubbish Lister” - Bộ liệt kê rác điện tử bệnh
hoạn. Chẳng ích gì mà biện minh xem cách gọi nào đúng
hơn, vì cả hai đều được Larry Wall, người sáng tạo và
kiến trúc sư chính, người cài đặt và bảo trì của Perl chấp
nhận. Ông ấy đã tạo ra Perl khi cố gắng sản xuất ra một
số báo cáo từ một cấp bậc các tệp kiểu như thư người
dùng mạng Usenet ở hệ thống báo lỗi, và lệnh awk làm
xì hết hơi. Larry, một người lập trình lười biếng, quyết

định thanh toán vấn đề này bằng một công cụ vạn nóng
mà ông có thể dùng ít nhất cũng ở một nơi khác. Kết quả
là bản đầu tiên của Perl.
Sau khi chơi với bản đầu này của Perl một chút,
thêm chất liệu đây đó, Larry đưa nó cho cộng đồng độc
Trong chương này:
 Lịch sử Perl
 Mục đích của Perl
 Có sẵn
 Hỗ trợ
 Các khái niệm cơ bản
 Dạo qua về Perl

2

giả Usenet, thường vẫn được gọi là “the Net”. Người
dùng thuộc toán người phù du nghèo khó về hệ thống
trên toàn thế giới (quãng độ chục nghìn người) đưa lại
cho anh ấy phản hồi, hỏi cách làm thế này thế kia, việc
này việc khác, nhiều điểm mà Larry chưa bao giờ mường
tượng ra về việc giải quyết cho Perl nhỏ bé của mình cả.
Nhưng kết quả là Perl trưởng thành, trưởng thành và
trưởng thành thêm nữa, và cũng cùng tỉ lệ như lõi của
UNIX. (với bạn là người mới, toàn bộ lõi UNIX được
dùng chỉ khít vào trong 32K! Và bây giờ chúng ta may
mắn nếu ta có thể có được nó dưới một vài mega.) Nó đã
trưởng thành trong các tính năng. Nó đã trưởng thành
trong tính khả chuyển. Điều mà có thời là một ngôn ngữ
tí tẹo bây giờ đã cả tài liệu sử dụng 80 trang, một cuốn
sách của Nutshell 400 trang, một nhóm tin Usenet với 40

nghìn thuê bao, và bây giờ là đoạn giới thiệu nhẹ nhàng
này.
Larry vẫn là người bảo trì duy nhất, làm việc trên
Perl ngoài giờ khi kết thúc công việc thường ngày của
mình. Và Perl thì vẫn phát triển.
Một cách đại thể lúc mà cuốn sách này đạt tới điểm
dừng của nó, Larry sẽ đưa ra bản Perl mới nhất, bản 5.0,
hứa hẹn có một số tính năng thường hay được yêu cầu,
và được thiết kế lại từ bên trong trở ra. (Larry bảo tôi
rằng không còn mấy dòng lệnh từ lần đưa ra trước, và số
ấy cứ ngày càng ít đi mỗi ngày.) Tuy nhiên, cuốn sách
này đã được thử với Perl bản 4.0 (lần đưa ra gần đây
nhất khi tôi viết điều này). Mọi thứ ở đây đó sẽ làm việc
với bản 5.0 và các bản sau của Perl. Thực ra, chương
trình Perl 1.0 vẫn làm việc tốt với những bản gần đây,
ngoại trừ một vài thay đổi là cần cho sự tiến bộ.

3

Mục đích của Perl
Perl được thiết kế để trợ giúp cho người dùng UNIX
với những nhiệm vụ thông dụng mà có thể rất nặng nề
hay quá nhạy cảm với tính khả chuyển đối với trình vỏ,
và cũng quá kì lạ hay ngắn ngủi hay phức tạp để lập trình
trong C hay một ngôn ngữ công cụ UNIX nào khác.
Một khi bạn trở nên quen thuộc với Perl, bạn có thể
thấy mình mất ít thời gian để lấy được trích dẫn trình vỏ
(hay khai báo C) đúng, và nhiều thời gian hơn để đọc tin
trên Usenet và đi trượt tuyết trên đồi; vì Perl là một công
cụ lớn tựa như chiếc đòn bẩy. Các cấu trúc chặt chẽ của

Perl cho phép bạn tạo ra (với tối thiểu việc làm ầm ĩ) một
số giải pháp có ưu thế rất trầm lặng hay những công cụ
tổng quát. Cũng vậy, bạn có thể lôi những công cụ này
sang công việc tiếp, vì Perl là khả chuyển cao độ và lại
có sẵn, cho nên bạn sẽ có nhiều thời gian hơn để đọc tin
Usenet và trượt tuyết.
Giống như mọi ngôn ngữ, Perl có thể “chỉ viết” - tức
là có thể viết ra chương trình mà không thể nào đọc
được. Nhưng với chú ý đúng đắn, bạn có thể tránh được
kết tội thông thường này. Quả thế, đôi khi Perl trông như
nổi tiếng với những cái không quen thuộc, nhưng với
người lập trình đã thạo Perl, nó tựa như những dòng có
tổng kiểm tra với một sứ mệnh trong cuộc đời. Nếu bạn
tuân theo những hướng dẫn của cuốn sách này thì
chương trình của bạn sẽ dễ đọc và dễ bảo trì, và chúng ta
có lẽ sẽ thắng trong bất kì cuộc tranh luận Perl khó hiểu
nào.
Tính sẵn có
Nếu bạn nhận được

4

Perl: not found
khi bạn thử gọi Perl từ lớp vỏ thì người quản trị hệ thống
của bạn cũng chẳng lên cơn sốt. Nhưng thậm chí nếu nó
không có trên hệ thống của bạn, thì bạn vẫn có thể lấy
được nó không mất tiền (theo nghĩa “ăn trưa không mất
tiền”).
Perl được phân phối theo giấy phép công khai GNU,
nghĩa là thế này, “bạn có thể phân phát chương trình nhị

phân Perl chỉ nếu bạn làm cho chương trình gốc có sẵn
cho mọi người dùng không phải trả tiền gì cả, và nếu bạn
sửa đổi Perl, bạn phải phân phát chương trình gốc của
bạn cho nơi sửa đổi của bạn nữa.” Và đó là bản chất của
cho không. Bạn có thể lấy chương trình gốc của Perl với
giá của một bảng trắng hay vài mêga byte qua đường
dây. Và không ai có thể khoá Perl và bán cho bạn chỉ mã
nhị phân với tư tưởng đặc biệt về “cấu hình phần cứng
được hỗ trợ.”
Thực ra, nó không chỉ là cho không, nhưng nó chạy
còn gọn hơn trên gần như mọi thứ mà có thể gọi là
UNIX hay tựa UNIX và có trình biên dịch C. Đấy là vì
bộ trình này tới với bản viết cấu hình bí quyết được gọi
là Cấu hình, cái sẽ móc và chọc vào các danh mục hệ
thống để tìm những thứ nó cần, và điều chỉnh việc đưa
vào các tệp và các kí hiệu được xác định tương ứng,
chuyển cho bạn việc kiểm chứng phát hiện của nó.
Bên cạnh các hệ thống UNIX hay tựa UNIX, người
đã bị nghiện Perl đem nó sang Amiga, Atari ST, họ
Macintosh, VMS, OS/2, thậm chí MS/DOS - và có lẽ
còn nhiều hơn nữa vào lúc bạn đọc cuốn sách này. vị trí
chính xác và sự có sẵn của những bản Perl này thì biến

5

động, cho nên bạn phải hỏi quanh (trên nhóm tin Usenet
chẳng hạn) để có được thông tin mới nhất. Nếu bạn hoàn
toàn không biết gì, thì một bản cũ của Perl đã có trên đĩa
phần mềm CD-ROM UNIX Power Tools, của Jerry Peek,
Tim O’Reilly và Mike Loukides (O’Reilly & Associates/

Random House Co., 1993).

Hỗ trợ
Perl là con đẻ của Larry Wall, và vẫn đang được anh
ấy nâng niu. Báo cáo lỗi và yêu cầu nâng cao nói chung
đã được sửa chữa trong các lần đưa ra sau, nhưng anh ấy
cũng chẳng có nghĩa vụ nào để làm bất kì cái gì với
chúng cả. Tuy thế Larry thực sự thích thú nghe từ tất cả
chúng ta, và cũng làm việc thực sự để thấy Perl được
dùng trên qui mô thế giới. E-mail trực tiếp cho anh ấy
nói chung đã nhận được trả lời (cho dù đấy chỉ đơn thuần
là máy trả lời email của anh ấy), và đôi khi là sự đáp ứng
con người.
Ích lợi hơn việc viết thư trực tiếp cho Larry là nhóm
hỗ trợ Perl trực tuyến toàn thế giới, liên lạc thông qua
nhóm tin Usenet comp.lang.perl. Nếu bạn có thể gửi
email trên Internet, nhưng chưa vào Usenet, thì bạn có
thể tham gia nhóm này bằng cách gửi một yêu cầu tới
, yêu cầu sẽ tới một
người có thể nối bạn với cửa khẩu email hai chiều trong
nhóm, và cho bạn những hướng dẫn về cách làm việc.
Khi bạn tham gia một nhóm tin, bạn sẽ thấy đại loại
có khoảng 30 đến 60 “thư” mỗi ngày (vào lúc bản viết
này được soạn thảo) trên đủ mọi chủ đề từ câu hỏi của
người mới bắt đầu cho tới vấn đề chuyển chương trình

6

phức tạp và vấn đề giao diện, và thậm chí cả một hay hai
chương trình khá lớn.

Nhóm tin gần như được những chuyên gia Perl điều
phối. Phần lớn thời gian, câu hỏi của bạn đã có trả lời
trong vòng vài phút khi tin của bạn tới đầu nối Usenet
chính. thử mức độ hỗ trợ từ nhà sản xuất phần mềm
mình ưa chuộng về việc cho không này! Bản thân Larry
cũng đọc về nhóm khi thời gian cho phép, và đôi khi đã
xen các bài viết có thẩm quyền vào để chấm dứt việc cãi
nhau hay làm sáng tỏ một vấn đề. Sau rốt, không có
Usenet, có lẽ không thể có chỗ để dễ dàng công bố Perl
cho cả thế giới.
Bên cạnh nhóm tin, bạn cũng nên đọc tạp chí Perl, đi
cùng việc phân phối Perl. Một nguồn có thẩm quyền
khác là cuốn sách Programming Perl của Larry Wall và
Randal L. Schwatrz (O’Reilly & Associates, 1990).
Programming Perl được xem như “Sách con lạc đà” vì
bìa của nó vẽ con vật này (hệt như cuốn sách này có lẽ sẽ
được biết tới với tên sách lạc đà không bướu). Sách con
lạc đà chứa thông tin tham chiếu đầy đủ về Perl dưới
dạng đóng gọn gàng. Sách con lạc đà cũng bao gồm một
bảng tra tham chiếu bật ra tài tình mà chính là nguồn ưa
chuộng của cá nhân tôi về thông tin Perl.

Các khái niệm cơ bản
Một bản viết vỏ không gì khác hơn là một dãy các
lệnh vỏ nhồi vào trong một tệp văn bản. Tệp này “được
làm cho chạy” bằng cách bật một bit thực hiện (qua
chmod +x filename) và rồi gõ tên của tệp đó vào lời nhắc

7


của vỏ. Bingo, một chương trình vỏ lớn. Chẳng hạn, một
bản viết để chạy chỉ lệnh date theo sau bởi chỉ lệnh who
có thể được tạo ra và thực hiện như thế này:
$ echo date > somecript
$ echo who > somecript
$ cat somescript
date
who
$ chmod _x somescript
$ somescript
[output of date followed by who]
$
Tương tự như thế, một chương trình Perl là một bộ
các câu lệnh và định nghĩa Perl được ném vào trong một
tệp. Rồi bạn bật bit thực hiện và gõ tên của tệp này tại lời
nhắc của vỏ. Tuy nhiên, tệp này phải chỉ ra rằng đây là
một chương trình Perl và không phải là chương trình vỏ,
nên chúng ta cần một bước phụ.
#! /usr/bin/perl
làm dòng đầu tiên của tệp này. Nhưng nếu Perl của
bạn bị kẹt vào một nơi không chuẩn, hay hệ điều hành
tựa UNIX của bạn không hiểu dòng #!, thì bạn có thêm
việc phải làm. Hỏi người cài đặt Perl về điều này. Các thí
dụ trong sách này giả sử rằng bạn dùng cơ chế thông
thường này.
Perl là một ngôn ngữ phi định dạng kiểu như C -
khoảng trắng giữa các hiệu bài (những phần tử của
chương trình, như print hay +) là tuỳ chọn, trừ phi hai
hiệu bài đi với nhau có thể bị lầm lẫn thành một hiệu bài
khác, trong trường hợp đó thì khoảng trắng thuộc loại

nào đó là bắt buộc. (Khoảng trắng bao gồm dấu cách,

8

dấu tab, dòng mới, về đầu dòng hay kéo giấy.) Có một
vài cấu trúc đòi hỏi một loại khoảng trắng nào đó ở chỗ
nào đó, nhưng chúng sẽ được trỏ ra khi ta nói tới chúng.
Bạn có thể giả thiết rằng loại và khối lượng khoảng trắng
giữa các hiệu bài là tuỳ ý trong các trường hợp khác.
Mặc dầu gần như tất cả các chương trình Perl đã có
thể được viết tất cả trên một dòng, một cách điển hình
chương trình Perl cũng hay được viết tụt lề như chương
trình C, với những phần câu lệnh lồng nhau được viết tụt
vào hơn so với phần bao quanh. Bạn sẽ thấy đầy những
thí dụ chỉ ra phong cách viết tụt lề điển hình trong toàn
bộ cuốn sách này.
Cũng giống như bản viết về vỏ, chương trình Perl
bao gồm tất cả các câu lệnh perl về tệp được lấy tổ hợp
chung như mọt trình lớn cần thực hiện. Không có khái
niệm về trình “chính” main như trong C.
Chú thích của Perl giống như chú thích của lớp vỏ
(hiện đại). Bất kì cái gì nằm giữa một dấu thăng (#) tới
cuối dòng đã là một chú thích. Không có khái niệm về
chú thích trên nhiều dòng như C.
Không giống hầu hết các lớp vỏ (nhưng giống như
awk và sed), bộ thông dịch Perl phân tích và biên dịch
hoàn toàn chương trình trước khi thực hiện nó. Điều này
có nghĩa là bạn không bao giờ nhận được lỗi cú pháp từ
chương trình một khi chương trình đã bắt đầu chạy, và
cũng có nghĩa là khoảng trắng và chú thích biến mất và

sẽ không làm chậm chương trình. Thực ra, giai đoạn biên
dịch này bảo đảm việc thực hiện nhanh chóng của các
thao tác Perl một khi nó được bắt đầu, và nó cung cấp
động cơ phụ để loại bỏ C như một ngôn ngữ tiện ích hệ

9

thống đơn thuần dựa trên nền tảng là C được biên dịch.
Việc biên dịch này không mất thời gian - sẽ là phi
hiệu quả nếu một chương trình Perl cực lớn lại chỉ thực
hiện một nhiệm vụ nhỏ bé chóng vánh (trong số nhiều
nhiệm vụ tiềm năng) và rồi ra, vì thời gian chạy cho
chương trình sẽ nhỏ xíu nếu so với thời gian dịch.
Cho nên Perl giống như một bộ biên dịch và thông
dịch. Nó là biên dịch vì chương trình được đọc và phân
tích hoàn toàn trước khi câu lệnh đầu tiên được thực
hiện. Nó là bộ thông dịch vì không có mã đích ngồi đâu
đó trút đầy không gian đĩa. Theo một cách nào đó, nó là
tốt nhất cho cả hai loại này. Phải thú thực, việc ẩn đi mã
đích đã dịch giữa những lời gọi thì hay, và đó là trong
danh sách mong ước của Larry cho Perl tương lai.

Dạo qua Perl
Chúng ta bắt đầu cuộc hành trình của mình qua Perl
bằng việc đi dạo một chút. Việc đi dạo này sẽ giới thiệu
một số các tính năng khác nhau bằng cách bổ sung vào
một ứng dụng nhỏ. Giải thích ở đây là cực kì ngắn gọn -
mỗi vùng chủ đề đã được thảo luận chi tiết hơn rất nhiều
về sau trong cuốn sách này. Nhưng cuộc đi dạo nhỏ này
sẽ cho bạn kinh nghiệm nhanh chóng về ngôn ngữ, và

bạn có thể quyết định liệu bạn có thực sự muốn kết thúc
cuốn sách này hay đọc thêm các tin Usenet hay chạy đi
chơi trượt tuyết.


10

Chương trình “Xin chào mọi người”
Ta hãy nhìn vào một chương trình nhỏ mà thực tế có
làm điều gì đó. Đây là chương trình “Xin chào mọi
người”:
#!/usr/bin/perl
print “Xin chào mọi người\n”;
Dòng đầu tiên là câu thần chú nói rằng đây là
chương trình Perl. Nó cũng là lời chú thích cho Perl -
nhớ rằng lời chú thích là bất kì cái gì nằm sau dấu thăng
cho tới cuối dòng, giống như hầu hết các lớp vỏ hiện đại
hay awk.
Dòng thứ hai là toàn bộ phần thực hiện được của
chương trình này. Tại đây chúng ta thấy câu lệnh print.
Từ khoá print bắt đầu chương trình, và nó có một đối,
một xâu văn bản kiểu C. Bên trong xâu này, tổ hợp kí tự
\n biểu thị cho kí tự dòng mới; hệt như trong C. Câu lệnh
print được kết thúc bởi dấu chấm phẩy (;). Giống như C,
tất cả các câu lệnh đơn giản đã kết thúc bằng chấm
phẩy
*
.
Khi bạn gọi chương trình này, phần lõi sẽ gọi bộ
thông dịch Perl, phân tích câu toàn bộ chương trình (hai

dòng, kể cả dòng chú thích đầu tiên) và rồi thực hiện
dạng đã dịch. Thao tác đầu tiên và duy nhất là thực hiện
toán tử print, điều này gửi đối của nó ra lối ra. Sau khi
chương trình đã hoàn tất, tiến trình Perl ra, cho lại một
mã ra thành công cho lớp vỏ.



*
Dấu chấm phẩy có thể bỏ đi khi câu lệnh này là câu lệnh cuối của
một khối hay tệp hay eval.

11

Hỏi câu hỏi và nhớ kết quả
Thêm một chút phức tạp hơn. Từ Xin chào mọi người
là một đụng chạm lạnh nhạt và cứng rắn. Làm cho
chương trình gọi bạn theo tên bạn. Để làm việc này, cần
một chỗ giữ tên, một cách hỏi tên, và một cách nhận câu
trả lời.
Một loại đặt chỗ giữ giá trị (tựa như một tên) là biến
vô hướng. Với chương trình này, ta sẽ dùng biến vô
hướng $name để giữ tên bạn. Chúng ta sẽ đi chi tiết hơn
trong Chương 2, Dữ liệu vô hướng, về những gì mà biến
này có thể giữ, và những gì bạn có thể làm với chúng.
Hiện tại, giả sử rằng bạn có thể giữ một số hay xâu (dãy
các kí tự) trong biến vô hướng.
Chương trình này cần hỏi về tên. Để làm điều đó,
cần một cách nhắc và một cách nhận cái vào. Chương
trình trước đã chỉ ra cho ta cách nhắc - dùng toán tử print.

Và cách để nhận một dòng từ thiết bị cuối là với toán tử
<STDIN>, mà (như ta sẽ dùng nó ở đây) lấy một dòng
cái vào. Gán cái vào này cho biến $name. Điều này cho
chương trình:
print “Tên bạn là gì? ”;
$name = <STDIN> ;
Giá trị của $name tại điểm này có một dấu dòng mới
kết thúc (Randal có trong Randal\n). Để vứt bỏ điều đó,
chúng ta dùng toán tử chop(), toán tử lấy một biến vô
hướng làm đối duy nhất và bỏ đi kí tự cuối từ giá trị xâu
của biến:
chop($name);
Bây giờ tất cả những gì cần làm là nói Xin chào, tiếp

12

đó là giá trị của biến $name, mà có thể thực hiện theo
kiểu vỏ bằng cách nhúng biến này vào bên trong xâu có
ngoặc kép:
print “Xin chào, $name!\n”;
Giống như lớp vỏ, nếu muốn một dấu đô la thay vì
tham chiếu biến vô hướng, thì có thể đặt trước dấu đô la
với một dấu sổ chéo ngược.
Gắn tất cả lại, ta được:
#!/usr/bin/perl
print “Tên bạn là gì? ”;
$name = <STDIN> ;
chop($name);
print “Xin chào, $name!\n”;


Bổ sung chọn lựa
Bây giờ ta muốn có một lời chào đặc biệt cho
Randal, nhưng muốn lời chào thông thường cho mọi
người khác. Để làm điều này, cần so sánh tên đã được
đưa vào với xâu Randal, và nếu hai xâu là một, thì làm
điều gì đó đặc biệt. Bổ sung thêm lệnh rẽ nhánh if-then-
else và phép so sánh vào chương trình:
#!/usr/bin/perl
print “Tên bạn là gì? ”;
$name = <STDIN> ;
chop($name);
if ($name eq “Randal”) {
print “Xin chào Randal! Tốt quá anh lại ở đây!\n”;
} else {
print “Xin chào, $name!\n”; # chào mừng thông
thường
}

13

Toán tử eq so sánh hai xâu. Nếu chúng bằng nhau
(từng kí tự một, và có cùng chiều dài), thì kết quả là
đúng. (Không có toán tử này trong C, và awk phải dùng
cùng toán tử cho xâu và số và tạo ra việc đoán có rèn
luyện.)
Câu lệnh if chọn xem khối câu lệnh nào (giữa các
dấu ngoặc nhọn sánh đúng) là được thực hiện - nếu biểu
thức là đúng, đó là khối thứ nhất, nếu không thì đó là
khối thứ hai.


Đoán từ bí mật
Nào, vì chúng ta đã có một tên nên ta để cho một
người chạy chương trình đoán một từ bí mật. Với mọi
người ngoại trừ Randal, chúng ta sẽ để cho chương trình
cứ hỏi lặp lại để đoán cho đến khi nào người này đoán
được đúng. Trước hết xem chương trình này và rồi xem
giải thích:
#! /usr/bin/perl
$secretword = “llama”; # từ bí mật
print “Tên bạn là gì?” ;
$name = <STDIN> ;
chop($name);
if ($name eq “Randal”) {
print “Xin chào, Randal! May quá anh ở đây!\n”;
} else {
print “Xin chào, $name!\n”; # chào thông thường
print “Từ bí mật là gì?” ;
$guess = <STDIN>;
chop($guess);
while ($guess ne $secrectword) {
print “Sai rồi, thử lại đi. Từ bí mật là gì?”;
$guess = <STDIN>;

×