intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Learning Perl - Giới thiệu qua về Perl part 3

Chia sẻ: AJFGASKJHF SJHDB | Ngày: | Loại File: PDF | Số trang:6

91
lượt xem
12
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Mặc dầu bạn có thể nghĩ về số và xâu như những vật rất khác nhau, nhưng Perl dùng chúng gần như là giống nhau, cho nên c húng ta sẽ nghiên c ứu c ả hai. Một giá trị vô hướng c ó thể được tác động bởi các toán tử (giống như phép c ộng hay ghép), và kết quả trả về nói chung

Chủ đề:
Lưu

Nội dung Text: Learning Perl - Giới thiệu qua về Perl part 3

  1. print "Chao Jenny! Lam bai tap di chu!\n"; } else { print "Xin chao ban $name!\n"; #chao thuong thuong print "Tu bi mat la gi? "; $guess = ; chop($guess); while (! good_word($name, $guess)) { print "Sai roi thu lai di. Tu bi mat la gi? "; $guess = ; chop($guess); } #ket thuc cua while } sub good_word { my ($somename, $someguess) = @_; #lay cac tham so $somename =~ s/\W.*//; #bo moi thu sau tu dau tien $somename =~ tr/A-Z/a-z/; #chuyen thanh chu thuong if ($somename eq "jenny") { #huh, Jenny, khong doan nua return 1; #tra ve True } elsif (($words{$somename} || "none") eq $someguess) { return 1; #tra ve True } else { return 0; #tra ve False } } #ket thuc good_word sub init_words { open(WORDSLIST, "wordslist"); while ($name = ) { chop($name); $word = ; chop($word); $words{$name} = $word; } close(WORDSLIST); } #ket thuc init_words Bây giờ nó đã bắt đầu trông giống một chương trình trưởng thành hoàn toàn. Chú ý đến dòng thực hiện được đầu tiên là lời gọi tới init_words(). Không có tham số nào được truyền c ả, cho nên c húng ta được tự do bỏ đi dấu ( ) (tuy nhiên tôi không khuyên bạn làm điều này). Cũng vậy, giá trị trả về tử init_words không được dùng biểu thức nào hết, thì c ũng là t ốt vì ta đã không trả về điều gì đáng kể. 1.6.11 Đảm bảo một lượng an toàn (nhỏ thôi- nhưng an toàn vẫn hơn) Xếp bạn quyết định: "Danh sách c ác từ bí mật phải thay đổi ít nhất một lần m ỗi tuần". c húng ta không thể buộc danh sách này khác đi, nhưng c húng ta có t hể ít nhất c ũng đưa ra một c ảnh báo nếu danh sác h từ bí mật còn c hưa được thay đổi trong hơn một tuần. Nơi tốt nhất để thực hiện việc kiểm tra là bên trong c hương trình c on init_words . Toán tử - M c ho lại "tuổi" tính theo ngày từ một tệp hay tước hiệu tệp đã được thay đổi từ lần t rước , c ho nên ta c hỉ c ần xem liệu giá trị này có lớn hơn 7 hay không đối với t ước hiệu tệp WORDSLIST: sub init_words { open(WORDSLIST, "wordslist"); if (-M WORDSLIST > 7) { die "Rat tiec, danh sach tu cu hon 7 ngay roi!"; } while ($name = ) { chop($name);
  2. chop($name); $word = ; chop($word); $words{$name} = $word; } close(WORDSLIST); } Giá trị của - M WORDSLIST được so sánh với 7, và nếu lớn hơn, thế thì ta vi phạm điều lệ an toàn rồi! Tại đây, ta thấy một toán tử mới: toán tử die. die c hỉ làm một c ông việc đơn giản là một thông báo lên thiết bị xuất và kết thúc c hương trình. Phần c òn lại c ủa c hương trình vẫn không đổi, c ho nên tôi sẽ không lặp lại nó ở đây. Bên c ạnh việc lấy số ngày c ủa tệp, ta c ũng c ó thể tìm ra người c hủ của nó, kíc h cỡ, thời gian thâm nhập, và mọi thứ khác mà UNIX duy trì về tệp. Nhiều điều hơn được trình bầy trong Chương 10. 1.6.12 Cảnh báo ai đó khi mọi việc đi sai Ta hãy xem ta có thể làm c ho hệ thống bị sa lầy thế nào khi ta gửi một mẩu t hư điện tử mỗi lần c ho một ai đó đoán từ bí mật c ủa họ không đúng. Ta c ần sửa đổi mỗi c hương trình c on good_word vì ta c ó tất c ả t hông tin ngay đây. Thư sẽ được gửi c ho bạn nếu bạn cũng c ấp địa c hỉ email của mình vào c hỗ "dia_c hi_c ua_ban_o_day". Đây là điều ta phải làm - ngay t rước khi trả 0 về từ c hương trình c on, ta tạo ra một tước hiệu tệp mà thực tại là một tiến trình (mail), giống như: sub good_word { my ($somename, $someguess) = @_; #lay cac tham so $somename =~ s/\W.*//; #bo moi thu sau tu dau tien $somename =~ tr/A-Z/a-z/; #chuyen thanh chu thuong if ($somename eq "jenny") { #huh, Jenny, khong doan nua return 1; #tra ve True } elsif (($words{$somename} || "none") eq $someguess) { return 1; #tra ve True } else { open(MAIL, "|mail dia_chi_cua_ban_o_day"); print MAIL "tin xau: $somename da doan $someguess\n”; return 0; #tra ve False } } #ket thuc good_word Câu lệnh mới thứ nhất ở đây là open(), mà có một kí hiệu | t rong tên tệp. Đây là một chỉ dẫn đặc biệt rằng ta đang mở một lệnh ngoài t hay vì một tệp. Vì nó nằm tại chỗ bắt đầu c ủa lệnh ngoài nên c ó nghĩa là ta đang mở một lệnh ngoài để ta c ó thể ghi-xuất t hông tin-lên nó (nếu bạn đặt | t ại cuối thay vì đầu t hì c ó nghĩa là bạn ở lệnh ngoài và đọc -thu tóm kết quả output c ủa lệnh). Câu lệnh tiếp, print , c ó một tước hiệu tệp (MAIL) giữa từ khoá print v à giá trị được in c ho ta biết là kết quả s ẽ được ghi lên MAIL t hay vì STDOUT . Cuối c ùng, ta đóng tước hiệu tệp MAIL, c ũng c ó nghĩa là kết thúc việc gởi dữ liệu ra lệnh ngoài. Perl c ó thể cũng gọi c ả c ác lệnh với việc kiểm soát chính xác trên danh sác h t ham số, mở c ác tước hiệu tệp, hay thậm c hí lôi ra c ả bản sao của c hương trình hiện tại, và thực hiện hai (hay nhiều) bản sao song song. Tất cả những điều này sẽ được mô tả trong Chương 14:Quản lí tiến trình. 1.6.13 Nhiều tệp từ bí mật trong thư mục hiện tại Ta hãy thay đổi định nghĩa c ủa tên tệp từ bí mật một c hút. Thay vì tệp được đặt tên là wordslist , thì ta hãy tìm bất kì tệp nào t rong thư mục hiện tại mà c ó tận c ùng là .sec ret . Nếu dùng c ác kịc h bản shell, bạn có thể sẽ dùng lệnh sau: echo *.secret để thu được một liệt kê ngắn gọn cho tất c ả c ác tên này. Như lát nữa bạn sẽ thấy, Perl dùng một cú pháp tên c hùm tương t ự. Ta lấy lại định nghĩa init_words: sub init_words {
  3. sub init_words { while ($filename = ) { open (WORDSLIST, $filename); if (-M WORDSLIST
  4. Ở (*) t a biết 3 điều: tên c ủa tệp (trong $filename), tên một ai đó (trong $name), và từ bí mật c ủa người đó (trong $word). Sau đây là c hỗ để c húng ta dùng c ông cụ sinh báo c áo của Perl. Ta định nghĩa một định dạng ở đâu đó trong chương trình (thông t hường gần cuối, giống như chương trình con): format STDOUT = @
  5. Hai dòng cuối c ủa định dạng này c ũng không c hứa t rường nào, c ho nên chúng được sao trực tiếp ra output. Do vậy định dạng này sinh ra bốn dòng, một trong đó c ó một phần bị thay đổi qua mỗi trang. Chỉ c ần thêm định nghĩa này vào chương trình trước là nó làm việc . Perl để ý đến định dạng đầu trang tự động. Perl c ũng c ó c ác trường được c anh giữa hay c ăn lề phải, và hỗ trợ c ho c ả c anh lề 2 bên. Chúng ta sẽ nói kỹ về vấn đề này trong Chương 11: Định dạng. 1.6.16 Làm "ấn tượng" cho danh sách từ cũ Khi ta đọc qua các tệp * .sec ret t rong thư mục hiện t ại, ta c ó thể tìm thấy các tệp quá c ũ (ta thường bỏ qua những tệp này từ t rước ). Ta hãy đi thêm một bước nữa - ta sẽ đổi tên c húng thành *.sec ret.old để c ho khi nhìn vào ta sẽ thấy ngay tệp những t ệp nào quá c ũ. Sau đây là c ách thức thể hiện cho c hương trình c on init_words với sửa đổi này: sub init_words { while ($filename = ) { open (WORDSLIST, $filename); if (-M WORDSLIST
  6. này là tên thông thường c ho DBM được gọi là lastdb). Các thuộc tính về tệp UNIX được dùng cho hai tệp này nếu c ác tệp đó phải được tạo ra (khi chúng c hưa có sẵn) là 0666. 0666 này c ó nghĩa là bất kì ai c ũng có thể đọc hay ghi lên tệp. (bạn xem thêm phần manual c ủa lệnh c homod). Câu lệnh thứ hai c hỉ ra rằng chúng ta dùng mảng băm đã được ánh xạ này giống hệt như mảng băm thông thường. Tuy nhiên, việc tạo ra hay c ập nhật một phần tử c ủa mảng sẽ tự động c ập nhật tệp đĩa tạo nên DBM. Điều này c ho mảng băm c ó một c uộc sống trải bên ngoài lời gọi hiện thời c ủa chương trình-một sự bền lâu c ủa riêng nó. Câu lệnh thứ ba ngắt mảng băm ra khỏi DBM, giống hệt t hao tác đóng tệp c lose(). Bạn c ó thể chèn thêm ba c âu lệnh này vào ngay đầu c ác định nghĩa c hương trình c on. Mặc dầu c ác câu lệnh được c hèn thêm này duy trì c ơ sở dữ liệu là tốt (và t hậm c hí c òn tạo ra nó trong lần ddầu), chúng ta vẫn không c ó c ác h nào để xem xét thông tin trong đó. Để làm điều đó, ta c ó thể tạo ra một chương trình chỏ t ác h biệt trông đại thể như thế này: #!/usr/bin/perl dbmopen(%last_good, "lastdb", 0666); foreach $name (sort keys(%last_good) { $when = $last_good{$name}; $hours = (time - $when) / 3600; #tinh gio da qua write; } dbmclose(%last_good); format STDOUT = User @
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
2=>2