Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 13 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
13
Dung lượng
46,03 KB
Nội dung
Định dạngĐịnhdạng là gì? Trong số nhiều việc làm đợc, Perl thờng đợc dùng làm ngôn ngữ trích rút và báo cáo thực hành. Đây là lúc biết về việc ngôn ngữ báo cáo đó. Perl cung cấp một khái niệm về tiêu bản viết báo cáo đơn giản, đợc gọi là định dạng. Địnhdạng xác định ra phần không đổi (tiêu đề cột, nhãn, văn bản cố định hay bất kì cái gì) và phần biến đổi (dữ liệu hiện tại mà bạn báo cáo). Hình dạng của địnhdạng thì rất gần với hình dạng của cái ra, tơng tự nh cái ra đã đợc địnhdạng trong COBL hay mệnh đề print using của một số ngôn ngữ BASIC. Việc dùng địnhdạng bao gồm ba điều sau: 1. Định nghĩa địnhdạng 2. Nạp dữ liệu cần in vào phần biến đổi của địnhdạng (trờng) 3. gọi tới địnhdạng Thờng thì bớc thứ nhất đợc thực hiện ngay (trong văn bản chơng trình sao cho nó đợc xác định vào lúc dịch), và hai bớc sau đợc thực hiện lặp đi lặp lại. Định nghĩa một định dạngĐịnhdạng đợc định nghĩa bằng việc dùng định nghĩa định dạng. Định nghĩa địnhdạng này có thể xuất hiện ở bất kì đâu trong văn bản chơng trình của bạn, giống nh chơng trình con. Định nghĩa địnhdạng trông tựa nh thế này: format tênđịnhdạng = dòngtrờng giá_trị_một, giá _trị_hai, giá _trị_ba dòngtrờng giá_trị_một, giá _trị_hai, giá _trị_ba dòngtrờng giá_trị_một, giá _trị_hai, giá _trị_ba . Dòng thứ nhất có chứa từ dành riêng format, tiếp đó là tên địnhdạng và rồi đến dấu bằng (=). Tên địnhdạng đợc chọn từ một không gian tên khác, và tuân theo cùng qui tắc nh mọi thứ khác. Vì tên địnhdạng không bao giờ đợc dùng bên trong thân ch- ơng trình (ngoại trừ bên trong giá trị xâu), nên bạn có thể an toàn dùng các tên trùng với với các từ dàng riêng. Nh bạn sẽ thấy trong mục sau, Gọi định dạng, phần lớn các tên địnhdạng của bạn có lẽ sẽ là một nh tên tớc hiệu tệp (mà thế thì làm cho chúng không phải là một nh các từ dành riêng) Tiếp theo sau dòng thứ nhất là bản thân tiêu bản, mở rộng từ không đến nhiều dòng văn bản. Phần cuối của tiêu bản đợc chỉ ra bằng một dấu chấm. Tiêu bản là nhậy cảm với khoảng trắng - đây là một trong vài chỗ mà một số khoảng trắng (dấu cách, xuống dòng, hay tab) gây ra vấn đề trong văn bản chơng trình Perl. Định nghĩa tiêu bản có chứa một chuỗi các dòng trờng. Mỗi dòng trờng có thể chứa văn bản cố định - văn bản sẽ đợc in ra theo từng kí tự khi địnhdạng này đợc gọi tới. Sau đây là một thí dụ về dòng trờng có văn bản cố định: Hello, my name is Fred Flintstone. Tên trờng có thể chứa cả nơi giữ trờng cho văn bản biến đổi. Nếu một dòng có chứa nơi giữ trờng, thì dòng tiếp sau của tiêu bản (đợc gọi là dòng giá trị) sẽ mô tả cho một loạt các giá trị vô hớng - mỗi giá trị ứng với một nơi giữ trờng - mà cung cấp ra giá trị sẽ đợc gắn vào trong trờng. Sau đây là một thí dụ về dòng trờng với một nơi giữ trờng, và dòng giá trị đi theo: Hello, my name is @<<<<<<<<<<<. $name Nơi giữ trờng là @<<<<<<<<<<<, sẽ xác định ra trờng văn bản đợc dồn trái bởi 11 kí tự. Các chi tiết đầy đủ hơn về nơi giữ trờng sẽ đợc nêu trong mục có tên Nói thêm về nơi giữ trờng dới đây. Nếu dòng trờng có nhiều nơi giữ trờng, thì nó cần nhiều giá trị, cho nên các giá trị đợc tách nhau bởi dấu phẩy: Hello, my name is @<<<<<<<<<<< and Im @<< years old $name, $age Gắn tất cả những điều này lại chúng ta có thể tạo ra một địnhdạng đơn giản cho một nhãn địa chỉ: format ADDRESSLABEL = ======================== | @<<<<<<<<<<<<<<<<<<<< | $name | @<<<<<<<<<<<<<<<<<<<< | $address | @<<<<<<<<<<<, @< @<<<< | $city, $state, $zip ======================== . Lu ý rằng các dòng có dấu bằng trên đỉnh và dới đáy của địnhdạng không có tr- ờng, và do vậy không có dòng giá trị theo sau. (Nếu bạn đặt một dòng giá trị đi theo sau dòng trờng nhu vậy, nó sẽ đợc diễn giải nh một dòng trờng khác, có thể không làm điều bạn muốn.) Khoảng trắng bên trong dòng giá trị bị bỏ qua. Một số ngời chọn việc dùng khoảng trống phụ trong dòng giá trị để nối dòng biến với nơi giữ trờng trên dòng trớc đó (nh đặt $zip ở dới trờng thứ ba của dòng trớc đó trong thí dụ này), nhng thế chỉ để mà trông thôi. Perl không quan tâm tới điều đó, và nó không ảnh hởng tới cái ra của bạn. Các giá trị đợc tính toán cho các giá trị vô hớng của chúng, cho nên tất cả các biểu thức đều đợc diễn giải theo ngữ cảnh vô hớng * . Văn bản theo sau dấu xuống dòng thứ nhất trong một giá trị bị bỏ qua (ngoại trừ trong trờng hợp đặc biệt nhiều nơi giữ trờng, sẽ đợc mô tả về sau). Định nghĩa địnhdạng cũng giống nh định nghĩa chơng trình con. Nó không chứa chơng trình thực hiện ngay lập tức, và do đó có thể đợc đặt ở bất kì đâu trong tệp với phần còn lại của chơng trình - tôi có khuynh hớng đặt những địnhdạng của mình vào cuối tệp, trớc các định nghĩa chơng trình con. Gọi một địnhdạng Bạn gọi tới một địnhdạng bằng toán tử write. Toán tử này lấy tên của tớc hiệu tệp, và sinh ra văn bản cho tớc hiệu tệp đó bằng việc dùng địnhdạng hiện thời cho tớc hiệu tệp đó. Theo ngầm định, địnhdạng hiện thời cho một tớc hiệu tệp là địnhdạng với cùng tên (cho nên với tớc hiệu tệp STDOUT, địnhdạng STDOUT sẽ đợc dùng), nhng chúng ta sẽ thấy ngay rằng bạn có thể thay đổi nó. Ta hãy lấy một thí dụ khác bằng việc xét địnhdạng nhãn địa chỉ, và tạo ra một tệp chứa các nãhn địa chỉ. Sau đây là một đoạn chơng trình: format ADDRESSLABEL = ======================== | @<<<<<<<<<<<<<<<<<<<< | $name | @<<<<<<<<<<<<<<<<<<<< | $address | @<<<<<<<<<<<, @< @<<<< | $city, $state, $zip ======================== . open (ADDRESSLABEL, >labels-to-print) || die cant create; open (ADDRESSLABEL, addresses) || die can not open addresses; while ( <ADDRESSES> ) { chop; # remove newline ($name, $address, $city, $state, $zip) = split (/:/) ; * * Trong Perl 5.0, tôi đợc biết rằng toàn bộ dòng bây giờ đợc tính theo ngữ cảnh mảng, cho nên phát biểu này là không đúng. Đáng phải nói khác đi nêu bạn có điều gì đó nh @a là một giá trị. # load up the global variables write ADDRESSLABEL; # send the output } Tại đây chúng ta thấy định nghĩa địnhdạng trớc, nhng bây giờ chúng ta cũng còn có thêm cả chơng trình thực hiện nữa. Trớc hết, chúng ta mở một tớc hiệu tệp lên một tệp ra đợc gọi là labels-to-print. Lu ý rằng tên tớc hiệu tệp (ADDRESSLABEL) là cùng tên của định dạng. Điều này là quan trọng. Tiếp đó, ta mở tớc hiệu tệp trên danh sách địa chỉ. Địnhdạng của danh sách địa chỉ đợc giả sử là một cái gì đó tựa nh: Stonehenge:4470 SW Hall Suite 107: Beaverton:OR:97005 Fred Flintstone:3737 Hard Rock Lane:Bedrock:OZ:999bc Nói cách khác, năm trờng tách biệt, mà chơng trìn hcủa ta sẽ phân tích nh mô tả dới đây. Chu trình while trong chơng trình này đọc từng dòng của tệp địa chỉ mỗi lúc, bỏ đi dấu xuống dòng, rồi chẻ dòng này (không có dấu xuống dòng) vào năm biến. Lu ý rằng các tên biến cũng là tên mà ta đã dùng khi định nghĩa định dạng. Điều này nữa cũng là quan trọng. Một khi ta có tất cả các biến đợc nạp vào (để cho các giá trị đợc địnhdạng sử dụng là đúng đắn), thì toán tử write gọi tới địnhdạng này. L ý rằng tham biến cho write là tớc hiệu tệp cần ghi ra và theo mặc địnhđịnhdạng cho cùng tên cũng đợc dùng. Mỗi trờng trong địnhdạng đều đợc thay thế bởi một giá trị tơng ứng từ dòng tiếp của định dạng. Sau khi hai bản ghi mẫu đợc nêu ở trên đã đợc xử lí, thì tệp labels-to- print có chứa: ===================== | Stonehege | | 4470 SW Hall Suite 107 | | Beaverton , OR 97005| ===================== ===================== | Fred Flintstone | | 3737 Hard Rock Lane | | Bedrock , OZ 999bc | ===================== Nói thêm về nơi giữ tệp Cho đến giờ, qua thí dụ, bạn đã biết rằng nơi giữ trờng @<<<< có nghĩa là một trờng đợc dồn trái với năm kí tự và rằng @<<<<<<<<<<< nghĩa là một trờng đợc dồn trái với 11 kí tự. Sau đây là toàn bộ phạm vi, nh đã hứa trớc đây. Trờng văn bản Phần lớn những nơi giữ trờng đều bắt đầu bằng @. Các kí tự đi sau @ chỉ ra kiểu của trờng, trong khi số các kí tự (kể cả @) chỉ ra chiều rộng của trờng. Nếu các kí tự đi sau @ là dấu mở ngoặc góc trái (<<<<) thì bạn nhận đợc một tr- ờng đợc dồn trái - tức là, giá trị sẽ đợc gắn thêm bên phải bằng dấu cách nếu giá trị này ngắn hơn chiều rộng trờng. (Nếu một giá trị quá dài thì nó sẽ bị chặt cụt tự động - dạng của địnhdạng bao giờ cũng đợc bảo tồn.) Nếu các kí tự đi sau @ là dấu đóng ngoặc góc phải (>>>>) thì bạn nhận đợc một trờng đợc dồn phải - tức là nếu giá trị quá ngắn, thì nó sẽ đợc bổ sung dấu cách vào bên trái. Cuối cùng, nếu các kí tự đi sau @ là dấu sổ đứng (| | | |) thì bạn nhận đợc một tr- ờng định tâm: nếu giá trị quá ngắn thì nó đợc bổ sung thêm dấu cách vào cả hai bên, đủ cho từng bên làm cho giá trị thành định tâm nhất bên trong trờng. Trờng số Một loại nơi giữ trờng khác là trờng số độ chính xác tĩnh, có ích cho những báo cáo tài chính lớn. Trờng này cũng bắt đầu với @, và đợc theo sau bởi một hay nhiều dấu # với một dấu chấm tuỳ chọn (chỉ ra dấu chấm thập phân). Một lần nữa, @ lại đ- ợc đếm nh một trong các kí tự của trờng. Chẳng hạn: format MONEY Assets: @#####.## Liabilities: @#####.## Net: @#####.## $assets, $liabilities, $assets-$liabilities . Ba trờng số cho phép sáu vị trí bên trái dấu chấm thập phân và hai vị trí bên phải (có ích cho đô la Mĩ và phần xu). Bạn hãy lu ý tới việc dùng một biểu thức theo địnhdạng - hoàn toàn hợp lệ và thờng hay đợc dùng. Perl không đa ra điều gì cho ngời thành thạo khác hơn điều này: bạn không thể nào lấy kí hiệu tiền trôi nổi hay dấu ngoặc nhọn quanh giá trị âm hay bất kì cái gì khác. Để làm điều đó, bạn phải viết chơng trình con của riêng mình, kiểu nh: format MONEYCOOL = Assets: @#####.## Liabilities: @#####.## Net: @#####.## &cool ($assets, 10), &cool ($liabilities, 9) , &cool ($assets-$liabilities, 10) . sub cool { local ($n, $width) = @_ ; $width -= 2 ; # back off for negative stuff $n = sprintf (%.2f, $n) ; # sprintf is in later chapter if ($n < 0) { sprintf ([%$width.2f], - $n) ; # negative numbers get spaces instead } } ## body of program: $assets = 32125.12; $liab = 45212.15; write MONEYCOOL; Trờng nhiều dòng Nh đã nói trớc đây, Perl thông thờng dừng tại dấu xuống dòng đầu tiên của một giá trị khi đặt kết quả vào đầu ra. Một loại nơi chứa trờng, nơi chứa trờng nhiều dòng, cho phép bạn đa vào một giá trị mà có thể có nhiều dòng thông tin. Nơi chứa trờng này đợc kí hiệu bởi @* trên một dòng bởi chính nó - bao giờ cũng vậy, dòng đi theo sau xác định ra giá trị mà sẽ đợc thế vào trong trờng này, mà trong trờng hợp này có thể là một biểu thức cho kết quả có chứa trên nhiều dòng. Giá trị đợc thế vào sẽ trông hệt nh văn bản gốc: bốn dòng của giá trị trở thành bốn dòng của cái ra. Chẳng hạn: format STDOUT = Text Before. @* $long_string Text After. . $long_string = Fred\nBaney\nBetty\nWilma\n; write ; sinh ra cái ra: Text Before. Fred Baney Betty Wilma Text After. Trờng đợc lấp đầy Môtt loại nơi chứa trờng khác là trờng đợc lấp đầy. Nơi chứa trờng này cho phép bạn tạo ra một đoạn đợc lấp đầy, bẻ văn bản thành các dòng có kích cỡ qui ớc tại biên giới từ, bao bọc dòng nếu cần. Có vài phần cùng làm việc ở đây, nhng chúng ta hãy xét chúng một cách tách biệt. Trớc hết, một trờng đợc lấp đầy đợc kí hiệu bằng việc thay thế dấu hiệu @ trong nơi chứa trờng văn bản bởi dấu mũ (vậy bạn nhận đợc ^<<<<, chẳng hạn). Giá trị t- ơng ứng cho trờng đợc lấp đầy (trên dòng tiếp của định dạng) phải là một biến vô h- ớng có chứa văn bản, thay vì một biểu thức cho lại một giá trị vô hớng. Lí do cho điều này là ở chỗ Perl sẽ thay đổi biến này trong khi rót đầy trờng đợc lấp, và cũng hơi khó để mà thay đổi một biểu thức. Khi Perl rót đầy trờng đợc lấp thì nó lấy giá trị của biến và vơ lấy nhiều từ (bằng việc dùng một định nghĩa hợp lí về từ) * đủ khít vào trong trờng. Những từ này thực tế vợt ra ngoài biến - giá trị của biến này sau khi rót đầy trờng này là bất kì cái gì bị bỏ lại sau khi loại bỏ từ. Bạn sẽ thấy tại sao ngay sau đây. Cho đến đây, điều này dờng nh không khác nhiều lắm với cách thức trờng văn bản làm việc - chúng ta chỉ in ra vừa đủ trờng (ngoại trừ rằng chúng ta vẫn tôn trọng biên giới từ thay vì cắt bỏ nó theo chiều rộng từ). Cái đẹp của trờng đợc rót này xuất hiện khi bạn có nhiều tham khảo tới cùng biến theo cùng định dạng. Ta hãy nhìn vào điều này: format PEOPLE = Name: @<<<<<<<<<<< Comment: ^<<<<<<<<<<<<<<<<<< $name, $comment Comment: ^<<<<<<<<<<<<<<<<<< $comment Comment: ^<<<<<<<<<<<<<<<<<< $comment Comment: ^<<<<<<<<<<<<<<<<<< $comment . Lu ý rằng biến $comment xuất hiện bốn lần. Dòng thứ nhất (dòng với trờng tên) in ra tên ngời và vài từ đầu của giá trị trong $comment. Nhng trong tiến trình tính dòng này, $comment bị thay đổi để cho các từ biến mất. Dòng thứ hai lại tham khảo đến cùng biến này ($comment), và do vậy sẽ lấy đi vài từ mới nữa từ cùng biến này. Điều này cũng đúng cho dòng thứ ba và thứ t. Một cách có hiệu quả, điều tôi đã tạo ra là một hình chữ nhật trong cái ra mà sẽ đợc rót đầy với các từ trong $comment trải qua bốn dòng. Điều gì xảy nếu toàn bộ văn bản chiếm ít hơn bốn dòng? Đợc, bạn sẽ đợc một hay hai dòng trống. Điều này có lẽ là đợc nếu bạn định in ra các nhãn và cần đúng cùng số dòng cho mỗi mục sánh đúng với nhãn đó. Nhng nếu bạn định in ra một báo cáo, thì nhiều dòng trống sẽ làm tốn giấy máy in của bạn. Để giải quyết vấn đề này, chúng ta có thể dùng một chỉ báo cắt bỏ. Bất kì dòng nào có chứa dấu ngã (~) đều bị cắt bỏ (không in ra) nếu dòng chỉ có dấu cách. Bản thân dấu ngã bao giờ cũng in ra nh dấu trống, và có thể đợc đặt ở bất kì đâu mà dấu cách có thể đợc đặt trong dòng. Viết lại thí dụ vừa rồi: format PEOPLE = * * Kí tự tách từ đợc định nghĩa bởi $:biến Name: @<<<<<<<<<<< Comment: ^<<<<<<<<<<<<<<<<<< $name, $comment ~ Comment: ^<<<<<<<<<<<<<<<<<< $comment ~ Comment: ^<<<<<<<<<<<<<<<<<< $comment ~ Comment: ^<<<<<<<<<<<<<<<<<< $comment . Bây giờ, nếu lời bình luận chỉ chiếm hai dòng, thì các dòng thứ ba và thứ t tự động bị cắt bỏ. Điều gì xảy ra nếu lời bình luận lại dài hơn bốn dòng? Đợc, chúng ta có thể tạo 20 bản sao cho hai dòng cuối của địnhdạng đó, hi vọng rằng 20 dòng sẽ đủ cho nó. Nhng điều đó lại đi ngợc với ý tởng rằng Perl giúp bạn lời biếng, cho nên có một cách lời biếng để thực hiện điều đó. Bất kì dòng nàocó chứa hai dấu ngã liên tiếp đều sẽ đ- ợc lặp lại một cách tự động cho tới khi kết quả là một dòng trống hoàn toàn. (Dòng trống bị cắt bỏ.) Điều này làm thay đổi địnhdạng của chúng ta trông giống thế này: format PEOPLE = Name: @<<<<<<<<<<< Comment: ^<<<<<<<<<<<<<<<<<< $name, $comment ~~ Comment: ^<<<<<<<<<<<<<<<<<< $comment . Cách này, nếu lời bình luận chiếm một, hai hay 20 dòng thì chúng ta vẫn giải quyết ổn thoả. Lu ý rằng tiêu chuẩn để chấm dứt dòng lặp lại đòi hỏi dòng phải trống tại điểm nào đó. Điều đó nghĩa là bạn có lẽ không muốn bất kì văn bản hằng nào (khác hơn dấu trống hay dấu ngã) trên dòng này, hay nếu không nó sẽ chẳng bao giờ trở thành trống. (Có đấy, Perl sẽ lặp mãi trong trờng hợp này. Điều này nghe đồn đã đợc giải quyết trong Perl 5.0) Địnhdạng đầu trang Nhiều báo cáo kết thúc trên một thiết bị in ra máy in nào đó. Giấy máy in thông thờng đợc cắt ra thành chùm các trang, bởi vì phần lớn chúng ta đã ngừng đọc giấy trong cuộn từ lâu rồi. Cho nên văn bản đợc nạp vào máy in về cơ bản phải tính tới biên giới trang để đa vào các dòng trống hay kí tự kéo trang để nhẩy qua chỗ d. Bây giờ bạn có thể lấy một cái ra của chơng trình Perl và nạp nó vào một trình tiện ích nào đó (có thể thậm chí là đợc viết trong Perl) mà làm việc phân trang này, nhng vẫn còn cách dễ hơn. Perl cho phép bạn xác địnhđịnhdạng đầu trang để cài bẫy xử lí trang. Perl đếm từng dòng đợc sinh ra và gọi tới địnhdạng cho một tớc hiệu tệp đặc biệt. Khi địnhdạng cái ra tiếp không còn khít vào phần còn lại của trang, thì Perl phun ra một dấu kéo trang tiếp sau đó tự động gọi tới địnhdạng đầu trang, và cuối cùng là in ra văn bản theo địnhdạng đã gọi. Theo cách đó, kết quả của một lần gọi write sẽ không bao giờ cắt ngang qua biên giới trang (tất nhiên trừ phinó quá lớn mà không thể khít trên chính bản thân trang). Địnhdạng đầu trang đợc xác định giống nh các địnhdạng khác. Tên mặc định cho địnhdạng đầu trang đối với một tớc hiệu tệp đặc biệt là giống nh tên của tớc hiệu tệp có theo sau bởi _TOP (xin hãy viết chữ hoa). Perl định nghĩa biến $% là số dòng của địnhdạng đầu trang mà đã đợc gọi cho một tớc hiệu tệp đặc biệt, cho nên bạn có thể dùng biến này trong địnhdạng đầu trang của mình để đánh số trang cho đúng. Chẳng hạn, việc thêm đinh nghĩa địnhdạng sau cho đoạn chơng trình trớc ngăn cản các nhãn không bị xé lẻ qua biên giới trang, và cũng đánh số trang liên tục: format ADDRESSLABEL_TOP = My Address -- Page @< $% . Chiều dài trang mặc định là 60 dòng. Bạn có thể thay đổi điều này bằng việc đặt một biến đặc biệt, đợc mô tả tóm tắt. Perl không để ý liệu bạn có dùng print để in lên cùng tớc hiệu tệp hay không cho nên nó có thể ném đi số dòng trên trang. Bạn có thể hoặc là viết lại chơng trình của mình để dùng các địnhdạng để gửi đi mọi thứ, hay tránh né biến số dòng trên trang hiện tại sau khi bạn thực hiện lệnh print. Chút nữa chúng ta sẽ thấy cách thay đổi giá trị này. Thay đổi mặc định cho địnhdạng Tôi thờng nói tới mặc định cho điều này điều nọ. Đợc, Perl cung cấp một cách để vợt qua các mặc định cho mọi bớc. Ta hãy nói về điều này. Dùng select() để thay đổi tớc hiệu tệp Quay trở lại khi ta nói về print, trong chơng 6, Cơ sở về vào/ra, tôi đã nói rằng print và print STDOUT là đồng nhất, bởi vì STDOUT là mặc định cho print. Không hẳn hoàn toàn thế. Mặc định thực cho print (và write cùng một vài phép toán khác mà ta sẽ gặp ngay sau đây) là một khái niệm kì cục đợc gọi là tớc hiệu tệp hiện đang đợc lựa. Tớc hiệu tệp hiện đang đợc lựa viết tắt là STDOUT - để làm cho nó dễ in mọi thứ trên đầu ra chuẩn. Tuy nhiên, bạn có thể thay thế tớc hiệu tệp hiện đang đợc lựa bằng toán tử select(). Toán tử này nhận một tớc hiệu tệp (hay biến vô hớng có chứa tên của tớc hiệu tệp) nh một đối. Một khi tớc hiệu tệp hiện đợc lựa mà thay đổi, thì nó ảnh h- ởng tới tất cả các phép toán tơng lai mà phụ thuộc vào tớc hiệu tệp hiện đợc lựa. Chẳng hạn: print hello world\n; # giống nh print STDOUT hello world\n; select(LOGFILE) ; # chọn một tớc hiệu tệp mới print howdy, world\n; giống nh print LOGFILE howdy world\n; print more for the log\n; # thêm về LOGFILE select (STDOUT); # chọn lại STDOUT print back to stdout\n; # lại trở về với đầu ra chuẩn Lu ý rằng phép toán select là khó tính - một khi bạn đã lựa một tớc hiệu mới thì nó vẫn còn có hiệu quả cho tới select tiếp. Cho nên, một định nghĩa tốt hơn cho STDOUT vẫn tôn trọng print và write là ở chỗ STDOUT là tớc hiệu hiện đợc lựa mặc định, hay tớc hiệu mặc định mặc định Các chơng trình con có thể thấy nhu cầu thay đổi tớc hiệu tệp hiện đợc lựa. Tuy nhiên, sẽ bất ngờ nếu bạn gọi một chơng trình con rồi phát hiện ra là tất cả các dòng văn bản bạn đã soạn công phu lại dòn thành một bó các bit nào đó bởi vì chơng trình con đã thay đổi tớc hiệu tệp hiện đợc lựa mà không khôi phục lại nó. Cho nên một ch- ơg trình con hành xử tốt cần phải làm gì? Nếu chơng trình con này biết rằng tớc hiệu hiện thời là STDOUT thì chơng trình con đó có thể khôi phục tớc hiệu đã lựa với ch- ơng trình tơng tự nh trên. Tuy nhiên, điều gì xẩy ra nếu nơi gọi chơng trình con này đã thay đổi tớc hiệu tệp đã lựa? Vậy vấn đề trở thành giá trị cho lại từ select là một xâu có chứa tên của tớc hiệu đã lựa trớc đó. Bạn có thể nắm lấy giá trị này để khôi phục tớc hiệu tệp đã lựa trớc đó, bằng việc dùng đoạn chơng trình nh thế này: $oldhandle = select(LOGFILE) ; print this goes to LOGFILE\n; select($oldhandle); # khôi phục tớc hiệu trớc đó Đấy, để làm thí dụ, thế thì dễ dàng hơn nhiều là chỉ cần đặt LOGFILE một cách t- ờng minh nh một tớc hiệu tệp cho print, nhng có một số thao tác đòi hỏi tớc hiệu tệp hiện đợc lựa phải thay đổi, nh ta sẽ thấy ngay sau đây. Thay đổi tên địnhdạng Tên địnhdạng ngầm định cho một tớc hiệu tệp là giống nh tớc hiệu tệp. Tuy nhiên, bạn có thể cthay đổi điều này cho tớc hiệu tệp hiện đợc lựa bằng việc thiết đặt tên địnhdạng mới trong một biến đặc biệt đợc gọi là $~. Bạn có thể cũng xem xét lại giá trị của biến này để xem địnhdạng hiện thời là gì đối với tớc hiệu tệp hiện đợc lựa. Chẳng hạn, để dùng . xác định vào lúc dịch), và hai bớc sau đợc thực hiện lặp đi lặp lại. Định nghĩa một định dạng Định dạng đợc định nghĩa bằng việc dùng định nghĩa định dạng. . Việc dùng định dạng bao gồm ba điều sau: 1. Định nghĩa định dạng 2. Nạp dữ liệu cần in vào phần biến đổi của định dạng (trờng) 3. gọi tới định dạng Thờng