The best way to make your Perl code look more like Perl code than C or basic code is to understand the built-in variables of Perl. Perl can use these built-in variables to control many aspects of program running. In this article, we will take a look at the outstanding performance of many built-in variables in the input and output control of files. Row count One reason I decided to write this article is that when I found that many people do not know the existence of the built-in variable "$.", I was surprised. I can still see that many people write code like this: Code My $ line_no = 0; While (<File> ){ ++ $ Line_no; Unless (/Some RegEx /){ Warn "error in line $ line_no/N "; Next; } # Process the record in some way } For some reason, many seem to have completely ignored the existence of "$. This variable is used to track the current record number. Therefore, the above Code can also be written as follows: Code While (<File>) { Unless (/Some RegEx /){ Warn "error in line $./N "; Next; } # Process the record in some way } Note: In layman's terms, this built-in variable is very similar to the record pointer in the database. Its value is the current row number in the file you are currently reading. Although using this built-in variable does not allow you to play less words, it is important that we can save unnecessary variable declarations. Another way to use this built-in variable is to use it with the continuous operator. When used in the list context, (...) is the list construction operator. It creates all elements between the given start and end elements. For example: Code My @ numbers = (1 .. 1000 ); @ Numbers will contain all integers from 1 to 1000. But when you use this operator in the context of an expression (for example, as a declared condition), its function is completely different. The first operand (the expression on the left side of "...") will be evaluated. If the obtained value is false, nothing will be done in this operation and a false value will be returned. If the obtained value is true, the operation returns the true value and returns the following values in sequence until the second operand (the expression on the right of the "..." operator) returns the true value. Let's give an example. Suppose you have a file and you only want to process some parts of the file. These parts are described "!! Start !! "Start ,"!! End !! "Indicates the end. Using Continuous operators, you can write this Code as follows: Code While (<File> ){ If (/!! Start !! /../!! End !! /){ # Process line } } For each loop, the continuous operator checks the current row. If the current row matches "/!", Start !! /"Does not match, the operator returns the dummy value and continues the loop. When the loop goes to the first and /!! Start !! /", The continuous operator returns the true value and executes the code in the IF statement block. In the loop after the while statement, the continuous operator checks "/!" again. End !! /", But it does not return the true value until it finds the matching row. This is to say in "!! Start !! "And "!! End !! "All rows between tags will be processed. When/! is found /!! End !! /, The continuous operator returns false and starts matching the first rule expression again. What is the relationship between these and "$? If one of the operands of a continuous operator is a constant, it is converted to an integer and matched with "$. Therefore, we can write code like this to output the first 10 lines of the file: Code While (<File> ){ Print if 1 .. 10; } The last thing to note about "$." Is that there is only one "$." variable in a program. If you are reading data from multiple file handles, the "$." variable saves the current record number in the recently read file handle. If you want a more complex solution to this problem, you can use IO: file objects. All these objects have an input_line_number method. Record Separator "$/" And "$/" are the input/output record separators respectively. When you read or write data, they mainly control what is used to define a "record ". Let me explain it in more detail. When you learn Perl for the first time and know the file input operator for the first time, you may be notified that "<File>" is read from a file. Each row contains a new line ("/N "). In fact, what you know is not completely true. It is only a special case. In fact, the file input operator ("<>") will contain a file input separator specified in "$/" after reading data. Let's take an example: Suppose you have a text file with interesting quotes, lyrics, or something else. For example: Code This is the definition of my life % We are far too young and clever % Stab a sorry heart With your favorite finger Here there are three quotes separated by a line "%. So how can we read a quote from this file one time. (Note: This quote can be a row or a row. For example, the first and second quotes in this example are both a row and the third quotes are two rows) One solution is to read a row from the file at a time and check whether the row is "% ". Therefore, we need to declare a variable to save the data that is read each time. When "%" is encountered, recombine the previously read data into a complete citation. Well, you still need to remember to process the last quote because it does not last "% ". This method is too complicated. A simple method is to change the content of the "$/" variable. The default value of this variable is a new line character ("/N"), which is why "<>" The operator reads the content of a file once. However, we can modify the variable content to any value we like. For example: Code $/= "%/N "; While (<quote> ){ Chomp; Print; } Every time we call "<>", Perl reads data from the file handle once until "%/N" is found. (Instead of reading a row at a time ). Therefore, when you use the chomp function to remove the row separator for reading data, the separator specified in the "$/" variable will be deleted. In the preceding example, all the data processed by the chomp Function %/N "is deleted. Change special variables of Perl Before proceeding, I need to remind you that you will receive a warning when you modify the values of these special variables. The problem is that most of these variables are forced in the main package. . That is to say, when you change the value of these variables, the program will give a warning about the value (including the modules you include. For example, if you are writing a module and you change the value of the "$/" variable in the module, when others apply your modules to their own programs, they must modify other modules accordingly. To adapt to program execution. Therefore, modifying the values of special variables may increase the difficulty of searching for buckets. Therefore, we should avoid it as much as possible. The first way to avoid this is to return the value of this special variable to the original value after you have used up the modified value of the special variable. For example: Code $/= "%/N "; While (<quote> ){ Chomp; Print; } $/= "/N "; Another problem caused by this method is that you are not sure that its value is the default value before you reset the value of a special variable. (Note: for example, if you have modified the value of the "$/" variable before "$/=" %/N ";" (not the default value "/N "), then you reset the default value at the end, which will certainly cause an error) Therefore, our code should be as follows: Code $ Old_input_rec_sep = $ /; $/= "%/N "; While (<quote> ){ Chomp; Print; } $/= $ Old_input_rec_sep; The above code avoids the bugs we mentioned above, but we have another method that looks more concise. This method uses local to define the "$/" variable. As follows: Code { Local $/= "%/N "; While (<quote> ){ Chomp; Print; } } We enclose the code in a pair of braces. Generally, code blocks are associated with loops, conditions, or subprograms. However, in Perl, you can use braces to separate a code block. Variables defined with local in this code block only play a role in the current code block. To sum up, it is a good habit not to change the built-in variables of Perl unless it is localized in a code block. Other values of "$ /" Here are some special values that you can assign to the "$/" variable. These values can enable some interesting behaviors. The first is to set the variable to undefined. This will enable the slurp mode, When this mode is enabled, all file content can be read from one file at a time. As follows: Code My $ file = do {local $/; <file> }; The return value of a DO statement block is the value of the last expression in the statement block. The return value of the above do statement block is the return value of the "<>" operator. And because the "$/" variable is set to UNDEF (undefined), the content of the entire file is returned. Note that you do not need to explicitly specify the "$/" variable as UNDEF, because all Perl variables are automatically initialized as UNDEF during definition. Setting the "$/" variable to UNDEF and null values is very important: setting a null value means enabling paragraph mode (that is, paragraph mode). In this mode, each record is a text section ending with one or more NULL actions. You may think that this effect is the same as setting the "$/" variable to "/n", but they still have a subtle difference. If the comparison is made, set the "$/" variable to "/n +" to be the same as the paragraph mode. (Note: here is just for example. In fact, you cannot set the "$/" variable as a rule expression) the last special value of the variable "$/" is that it can be set as a reference of an integer scalar variable or an integer constant. In this case, the maximum data read from the file handle is the size specified by the "$/" variable. (Here I say "most" because the remaining data size may be smaller than the size specified by the "$/" variable at the end of the file ). Therefore, if you want to read 2 kb of data each time, you can do this: Code { Local $ // =/2048; While (<File> ){ # $ _ Contains the next 2048 bytes from File } } "$/" And "$ ." Note that when the value of the "$/" variable is changed, Perl's definition of the record also changes the behavior of the "$." variable. The variable "$." actually saves the current record number instead of the current row number. Therefore, in the cited example above, the "$." variable increases progressively according to each citation in the file where you want to read the data. About "$ /" At the beginning, I mentioned the "$/" and "$/" variables as the record separator for input and output. However, we have never introduced the "$/" variable. To be honest, "$/" is not as useful as "$. It contains the string to be added at the end of each call to print output. Its default value is a Null String, so when you use print for output, nothing is behind the output data. Of course, if you really want to have an output function like Pascal, we can write it like this: Code Sub println { Local $/= "/N "; Print @_; } In this way, each time you use print to output data, a "/N" (line break) will be added to the data ). Other print Variables The next two variables that need to be discussed are very confusing, although they do two completely different things. For example, let's look at the following code: Code My @ arr = (1, 2, 3 ); Print @ arr; Print "@ arr "; Do you know the difference between the two print calls? The answer is that the first print call is next to the three elements in the output array, and there is no separator (the output is 123 ). However, the elements output by the second print statement are indeed separated by spaces (output: 1 2 3 ). Why is the difference? The key to understanding this problem is what is actually passed to print in each case. In the first case, an array is passed to print. Perl splits the passed array into a list. The three elements in the list are considered as separate parameters. In the second case, the array is enclosed by double quotation marks before being passed to print. The second case can also be understood as the following process: Code My $ string = "@ arr "; Print $ string; Therefore, in the second case, only one parameter is passed to the print function. In fact, the result is to enclose an array with double quotation marks, without affecting how the print function treats the string. Therefore, we are faced with two situations. When print receives a set of parameters, it will compact these parameters and there is no space between the output parameters. When an array is Before double quotation marks are included and passed to print, each element of the array is expanded as a string using a space separator. These two cases are completely irrelevant. However, from the examples above, we can easily see how people confuse these two situations. Of course, if we want to, Perl allows us to change this behavior. The "$," variable saves the strings used to separate the parameters passed to the print function. As described above, by default, the characters used to separate the print parameter are null characters, which can be changed: Code My @ arr = (1, 2, 3 ); { Local $, = ','; Print @ arr; } This code will output 1, 2, 3 Correspondingly, when an array is enclosed by double quotation marks and passed to the print function, the characters used to split the elements after expanding the array are saved in the "$" variable. The Code is as follows: Code My @ arr = (1, 2, 3 ); { Local $ "= '+ '; Print "@ arr "; } This code will output 1 + 2 + 3 Of course, the "$" variable is not required in the use of a print statement. You can use it in any array containing double quotes. It is not only effective for arrays. It can also be used in hash tables. Code My % hash = (one => 1, two => 2, three => 3 ); { Local $ "= '<'; Print "@ hash {QW (One Two Three )}"; } This will output: 1 <2 <3 Http://bbs.chinaunix.net/thread-1191868-1-1.html # |