summaryrefslogtreecommitdiff
path: root/eg
Commit message (Collapse)AuthorAgeFilesLines
* perl 4.0.00: (no release announcement available)perl-4.0.00Larry Wall1991-03-2129-29/+35
| | | | So far, 4.0 is still a beta test version. For the last production version, look in pub/perl.3.0/kits@44.
* perl 3.0 patch #40 patch #38, continuedLarry Wall1990-11-091-3/+3
| | | | See patch #38.
* perl 3.0 patch #37 (combined patch)Larry Wall1990-10-191-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | I tried to take the strlen of an integer on systems without wait4() or waitpid(). For some reason this didn't work too well... In hash.c there was a call to dbm_nextkey() which needed to be ifdefed on old dbm systems. A pattern such as /foo.*bar$/ was wrongly optimized to do tail matching on "foo". This was a longstanding bug that was unmasked by patch 36. Some systems have some SYS V IPC but not all of it. Configure now figures this out. Patch 36 put the user's PATH in front of Configures, but to make it work right I needed to change all calls of loc to ./loc in Configure. $cryptlib needed to be mentioned in the Makefile. Apollo 10.3 and Sun 3.5 have some compilation problems, so I mentioned them in README. Cray has weird restrictions on setjmp locations--you can't say if (result = setjmp(...)) Random typos and cleanup.
* perl 3.0 patch #32 patch #29, continuedLarry Wall1990-10-163-0/+143
| | | | See patch #29.
* perl 3.0 patch #29 (combined patch)Larry Wall1990-10-151-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This set of patches pretty much brings you up to the functionality that version 4.0 will have. The Perl Book documents version 4.0. Perhaps these should be called release notes... :-) Enhancements: Many of the changes relate to making the debugger work better. It now runs your scripts at nearly full speed because it no longer calls a subroutine on every statement. The debugger now doesn't get confused about packages, evals and other filenames. More variables (though still not all) are available within the debugger. Related to this is the fact that every statement now knows which package and filename it was compiled in, so package semantics are now much more straightforward. Every variable also knows which package it was compiled in. So many places that used to print out just the variable name now prefix the variable name with the package name. Notably, if you print *foo it now gives *package'foo. Along with these, there is now a "caller" function which returns the context of the current subroutine call. See the man page for more details. Chip Salzenberg sent the patches for System V IPC (msg, sem and shm) so I dropped them in. There was no way to wait for a specific pid, which was silly, since Perl was already keeping track of the information. So I added the waitpid() call, which uses Unix's wait4() or waitpid() if available, and otherwise emulates them (at least as far as letting you wait for a particular pid--it doesn't emulate non-blocking wait). For use in sorting routines, there are now two new operators, cmp and <=>. These do string and numeric comparison, returning -1, 0 or 1 when the first argument is less than, equal to or greater than the second argument. Occasionally one finds that one wants to evaluate an operator in a scalar context, even though it's part of a LIST. For this purpose, there is now a scalar() operator. For instance, the approved fix for the novice error of using <> in assigning to a local is now: local($var) = scalar(<STDIN>); Perl's ordinary I/O is done using standard I/O routines. Every now and then this gets in your way. You may now access the system calls read() and write() via the Perl functions sysread() and syswrite(). They should not be intermixed with ordinary I/O calls unless you know what you're doing. Along with this, both the sysread() and read() functions allow you an optional 4th argument giving an offset into the string you're reading into, so for instance you can easily finish up partial reads. As a bit of syntactic sugar, you can now use the file tests -M, -A and -C to determine the age of a file in (possibly fractional) days as of the time the script started running. This makes it much easier to write midnight cleanup scripts with precision. The index() and rindex() functions now have an optional 3rd argument which tells it where to start looking, so you can now iterate through a string using these functions. The substr() function's 3rd argument is now optional, and if omitted, the function returns everything to the end of the string. The tr/// translation function now understands c, d and s options, just like the tr program. (Well, almost just like. The d option only deletes characters that aren't in the replacement string.) The c complementes the character class to match and the s option squishes out multiple occurrences of any replacement class characters. The reverse function, used in a scalar context, now reverses its scalar argument as a string. Dale Worley posted a patch to add @###.## type fields to formats. I said, "Neat!" and dropped it in, lock, stock and sinker. Kai Uwe Rommel sent a bunch of MSDOS and OS/2 updates, which I (mostly) incorporated. I can't vouch for them, but they look okay. Any data stored after the __END__ marker can be accesses now via the DATA filehandle, which is automatically opened onto the script at that point. (Well, actually, it's just kept open, since it was already open to read the script.) The taintperl program now checks for world writable PATH components, and complains if any are found (if PATH is used). Bug fixes: It used to be that you could get core dumps by such means as @$foo=(); @foo[42]; (1,2,3)[42]; $#foo = 50; foreach $elem (@foo) { $elem = 1; } This is no longer so. (For those who are up on Perl internals, the stack policy no longer allows Nullstr--all undefined values must be passed as &str_undef.) If you say something like local($foo,$bar); or local($initialized,$foo,$bar) = ('one value'); $foo and $bar are now initialized to the undefined value, rather than the defined null string. Array assignment to special arrays is now better supported. For instance, @ENV = () clears the environment, and %foo = () will now clear any dbm file bound to %foo. On the subject of dbm files, the highly visible bugs at patchlevel 28 have been fixed. You can now open dbm files readonly, and you don't have to do a dummy assignment to make the cache allocate itself. The modulus operator wasn't working right on negative values because of a misplaced cast. For instance, -5 % 5 was returning the value 5, which is clearly wrong. Certain operations coredumped if you didn't supply a value: close; eof; Previously, if the subroutine supplied for a sort operation didn't exist, it failed quietly. Now it produces a fatal error. The bitwise complement operator ~ didn't work on vec() strings longer than one byte because of failure to increment a loop variable. The oct and hex functions returned a negative result if the highest bit was set. They now return an unsigned result, which seems a little less confusing. Likewise, the token 0x80000000 also produces an unsigned value now. Some machines didn't like to see 0x87654321 in an #ifdef because they think of the symbols as signed. The tests have been changed to just look at the lower 4 nybbles of the value, which is sufficient to determine endianness, at least as far as the #ifdefs are concerned. The unshift operator did not return the documented value, which was the number of elements in the new array. Instead it returned the last unshifted argument, more or less by accident. -w sometimes printed spurious warnings about ARGV and ENV when referencing the arrays indirectly through shift or exec. This was because the typo test was misplaced before the code that exempts special variables from the typo test. If you said 'require "./foo.pl"', it would look in someplace like /usr/local/lib/perl/./foo.pl instead of the current directory. This works more like people expect now. The require error messages also referred to wrong file, if they worked at all. The h2ph program didn't translate includes right--it should have changed .h to .ph. Patterns with multiple short literal strings sometimes failed. This was a problem with the code that looks for a maximal literal string to feed to the Boyer-Moore searching routine. The code was gluing together literal strings that weren't continuous. The $* variable controls multi-line pattern matching. When it's 0, patterns are supposed to match as if the string contained a single line. Unfortunately, /^pat/ occasionally matched in middle of string under certain conditions. Recently the regular expression routines were upgraded to do {n,m} more efficiently. In doing this, however, I manufactured a couple of bugs: /.{n,m}$/ could match with fewer than n characters remaining on the line, and patterns like /\d{9}/ could match more than 9 characters. The undefined value has an actual physical location in Perl, and pointers to it are passed around. By certain circuitous routes it was possible to clobber the undefined value so that it was no longer undefined--kind of like making /dev/null into a real file. Hopefully this can't happen any more. op.stat could fail if /bin/0 existed, because of a while (<*>) {... This has been changed to a while (defined($_ = <*>)) {... The length of a search pattern was limited by the length of tokenbuf internally. This restriction has been removed. The null character gave the tokener indigestion when used as a delimiter for m// or s///. There was a bunch of other cleanupish things that are too trivial to mention here.
* perl 3.0 patch #25 patch #19, continuedLarry Wall1990-08-082-14/+134
| | | | See patch #19.
* perl 3.0 patch #14 patch #13, continuedLarry Wall1990-03-122-8/+8
| | | | See patch #13.
* perl 3.0 patch #12 patch #9, continuedLarry Wall1990-02-283-3/+78
| | | | See patch #9.
* perl 3.0 patch #11 patch #9, continuedLarry Wall1990-02-281-7/+8
| | | | See patch #9.
* perl 3.0 patch #9 (combined patch)Larry Wall1990-02-281-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Well, I didn't quite fix 100 things--only 94. There are still some other things to do, so don't think if I didn't fix your favorite bug that your bug report is in the bit bucket. (It may be, but don't think it. :-) There are very few enhancements here. One is the new pipe() function. There was just no way to emulate this using the current operations, unless you happened to have socketpair() on your system. Not even syscall() was useful in this respect. Configure now determines whether volatile is supported, since some compilers implement volatile but don't define __STDC__. Some compilers can put structure members and global variables into registers, so more variables had to be declared volatile to avoid clobbering during longjmp(). Some systems have wanted routines stashed away in libBSD.a and libPW.a. Configure can now find them. A number of Configure tests create a file called "try" and then execute it. Unfortunately, if there was a "try" elsewhere in PATH it got that one instead. All references are now to "./try". On Ultrix machines running the Mips cpu, some header files define things differently for assembly language than for the C language. To differentiate these, cc passes a -DLANGUAGE_C to the C preprocessor. Unfortunately, Configure, makedepend and perl want to use the preprocessor independently of cc. Configure now defaults to adding -DLANGUAGE_C on machines containing that symbol in signal.h. In Configure, some libraries were getting into the list more than once, causing extra extraction overhead. The names are now uniquified. Someone has invented yet another output format for nm. Sigh. Why do people assume that only people read the output of programs? Due to commentary between a declaration and its semicolon, some standard versions of stdio weren't being considered standard, and the type of char used by stdio was being misidentified. People trying to use bison instead of yacc ran into two problems. One, lack of alloca(), is solved on some machines by finding libPW.a. The other is that you have to supply a -y switch to bison to get it to emulate yacc naming conventions. Configure now prompts correctly for bison -y. The make clean had a rm -f $suidperl where it just wanted a rm -f suidperl In the README, documented more weirdities on various machines, including a pointer to the JMPCLOBBER symbol. In the construct OUTER: foreach (1,2,3) { INNER: foreach (4,5) { ... next OUTER; } } the inner loop was not getting reset to the first element. This was one of those bugs that arise because longjmp() doesn't execute exit handlers as it unwinds the stack. Perl reallocs many things as they grow, including the stack (its stack, not the C program's stack). This means that routines have to be careful to retreive the new stack when they call subroutines that can do such a realloc. In cmd.c there was such code but it was hidden inside an #ifdef JMPCLOBBER that it should have been outside of, so you could get bad return values of JMPCLOBBER wasn't defined. If you defined JMPCLOBBER to work around this problem, you should consider undefining it if your compiler guarantees that register variables get the value they had either at setjmp() or longjmp() time. Perl runs slightly faster without JMPCLOBBER defined. The longjmp()s that perl does return known values, but as a paranoid programming measure, it now checks that the values are one of the expected ones. If you say something like while (s/ /_/) {} the substitution almost always succeeds (on normal text). There is an optimization that quickly discovers and bypasses operations that are going to fail, but does nothing to help generally successful ones such as the one above. So there's a heuristic that disables the optimization if it isn't buying us anything. Unfortunately, in the above case, it's in the conditional of a while loop, which is duplicated by another optimization to be a last unless s/ /_/; at the end of the loop, to avoid unnecessary subroutine calls. Because the conditional was duplicated (not the expression itself, just the structure pointing to it), the heuristic mentioned above tried to disable the first optimization twice, resulting in the label stack getting corrupted. Some subroutines which mix both return mechanisms like this: sub foo { local($foo); return $foo if $whatever; $foo; } This clobbered the return value of $foo when the end of the scope of the local($foo) was reached. This was because such a routine turns into something like this internally: sub foo { _SUB_: { local($foo); if ($whatever) { $foo; last _SUB_; } $foo; } } Because the outer _SUB_ block was manufactured by non-standard means, it wasn't getting marked as an expression that could return a value, ie a terminal expression. So the return value wasn't getting properly saved off to the side before the local() exited. The internal label on subroutine blocks used to be SUB, but I changed it to _SUB_ to avoid possible confusion. Evals now have labels too, so they are labelled with _EVAL_. The reason evals now have a label is that nested evals need separate longjmp environments, or fatal errors end up getting a longjmp() botch. So eval now uses the same label stack as loops and subroutines. The eval routine used to always return undef on failure. In an array context, however, this makes a non-null array, which when assigned is TRUE, which is counter-intuitive. It now returns a null array upon failure in an array context. When a foreach operator works on a non-array, the compiler translates foreach (1,2,3) { into something like @_GEN_0 = (1,2,3); foreach (@_GEN_0) { Unfortunately, the line number was not correctly propagated to both command structures, so huge line numbers could appear in error messages and while debugging. The x operator was stupidly written, just calling the internal routine str_scat() multiple times, and not preextending the string to the known new length. It now preextends the string and calls a special routine to replicate the string quickly. On long strings like '\0' x 1024, the operator is more than 10 times faster. The split operator is supposed to split into @_ if called in a scalar context. Unfortunately, it was also splitting into @_ in an array context that wasn't a real array, such as assignment to a list: ($foo,$bar) = split; This has now been fixed. The split and substitute operators have a check to make sure that it isn't looping endlessly. Unfortunate, they had a hardwired limit of 10000 iterations. There are applications conceivable where you could work on longer values than that, so they now calculate a reasonable limit based on the length of the arguments. Pack and unpack called atoi all the time on the template fields. Since there are usually at most one or two digits of number, this wasted a lot of time on machines with slow subroutine calls. It now picks up the number itself. There were several places that casts could blow up. In particular, it appears that a sun3 can't cast a negative float to an unsigned integer. Appropriate measure have been taken--hopefully this won't blow someone else up. A local($.) didn't work right because the actual value of the current line number is derived from the last input filehandle. This has been fixed by causing the last input filehandle to be restored after the scope of a local($.) to what it was when the local was executed. Assignment is supposed to return the final value of the left hand side. In the case of array assignment (in an array context), it was actually returning the right hand side. This showed up in things that referred to the actual elements of an array value, such as grep(s/foo/bar/, @abc = @xyz), which modified @xyz rather than @abc. The syscall() function was returning a garbage value (the index of the top of the stack, actually) rather than value of system call. There was some discussion about how to open files with arbitrary characters in the filename. In particular, the open function strips trailing spaces. There was no way to suppress this. Now you can put an explicit null at the end of the string open(FOO,"$filename\0") and this will hide any spaces on the end of the filename. The Unix open() function will of course treat the null as the trailing delimiter. As a hangover from when Perl was not useful on binary files, there was a check to make sure that the file being opened was a normal file or character special file or socket. Now that Perl can handle binary data, this is useless, and has been removed. Some versions of utime.h have microseconds specified as acusec and modusec. Perl was referring to these in order to zero out the fields. But not everyone has these. Perl now just bzero's out the structure and refers only to fields that everyone has. You used to have to say ($foo) = unpack("L",$bar); Now you can say $foo = unpack("L",$bar); and it will just unpack the first thing specified by the template; The subscripts for slices were ignoring the value of $[. (This never made any difference for people who leave $[ set to 0.) It seems reasonable that grep in a scalar context should return the number of items matched so that it can be used in, say, a conditional. Formerly it returned an undef. Another problem with grep was that if you said something like grep(/$1/, @foo) then each iteration of grep was executing in the context of the previous iteration's regexp, so $1 might be wiped out after the first iteration. All iterations of grep now operate in the regexp context of the grep operator itself. The eg/README file now explicity states that the examples in the eg directory are to be considered in the Public Domain, and thus do not have the same restrictions as the Perl source. In a previous patch the shift operator was made to shift @_ inside of subroutines. This made some of the getopt code wrong. The sample rename command (and the new relink command) can either take a list of filenames from stdin, or if stdin is a terminal, default to a * in the current directory. A sample travesty program is now included. If you want to know what it does, feed it about 10 Usenet articles, or the perl manual, and see what it prints out. If a return operator was embedded in an expression that supplied a scalar context, but the subroutine containing the return was called in an array context, an array was not returned correctly. Now it is. The !~ operator used to ignore the negation in an array context and do the same thing as =~. It now always returns scalar even in array context, so if you say ($foo) = ($bar !~ /(pat)/) $foo will get a value of either 1 or ''. Opens on pipes were defined to return the child's pid in the parent, and FALSE in the child. Unfortunately, what the child actually got was an undef, making it indistinguishable from a failure to open the pipe successfully. The child now gets a 0, and undef means a failure to fork a child. Formerly, @array in a scalar context returned the last value of the array, by analogy to the comma operator. This makes for counter-intuitive results when you say if (@array) if 0 or '' is a legal array value. @array now returns the length of the array (not the subscript of the last element, which is @#array). To get the last element of the array you must either pop(@array) or refer to $array[$#array]. The chdir operator with no argument was supposed to change directory to your home directory, but it core dumped instead. The wait operator was ignoring SIGINT and SIGQUIT, by analogy to the system and pipe operations. But wait is a lower level operation, and it gives you more freedom if those signals aren't automatically ignored. If you want them ignored, you now have to explicitly ignore them by setting the proper %SIG entry. Different versions of /bin/mkdir and /bin/rmdir return different messages upon failure. Perl now knows about more of them. -l FILEHANDLE now disallowed The use of the -l file test makes no sense on a filehandle, since you can't open symbolic links. So -l FILEHANDLE now is a fatal error. This also means you can't say -l _, which is also a useless operation. The heavy wizardry involved in saying $#foo -= 2 didn't work quite right. In formats, you can say ... in a ^ field to have ... output when there is more for that field that is getting truncated. The next field was getting shifted over by three characters, however. The perl library routines abbrev.pl, complete.pl, getopt.pl and getopts.pl were assuming $[ == 0. The Getopt routine wasn't returning an error on unrecognized switches. The look.pl routine had never been tested, and didn't work at all. Now it does. There were several difficulties in termcap.pl. Togoto was documented backwards for $rows and $cols. The Tgetent routine could loop endlessly if there was a tc entry. And it didn't interpret the ^x form of specifying control characters right because of base treachery (031 instead of 31). There were also problems with using @_ as a temporary array. In perl.h, the unused VREG symbol was deleted because it conflicted with somebody's header files. If perl detects a #! line that specifies some other interpreter than perl, it will now start up that interpreter for you. This let's you specify a SHELL of perl to some programs. The $/ variable specifies the input record separator. It was possible to set it to a non-text character and read in an entire text file as one input, but it wasn't possible to do that for a binary file. Now you can undef $/, and there will be no record separator, so you are guaranteed to get the entire file with one <>. The example in the manual of an open() inside a ?: had the branches of the ?: backwards. I documented the fact that grep can modify arrays in place (with caveats about modifying literal values). I also put in how to deal with filenames that might have arbitrary characters, and mentioned about the problem of unflushed buffers on opens that cause forks. It's now documented how to force top of page before the next write. Formerly, $0 was guaranteed to contain the name of the perl script only till the first regular expression was executed. It now keeps that value permanently. $0 can no longer be used as a synonym for $&. The regular expression evaluator didn't handle character classes with the 8th bit set. None of /[\200-\377]/, \d, \w or \s worked right--the character class because signed characters were not interpreted right, and the builtins because the isdigit(), isalpha() and isspace() macros are only defined if isascii() is true. Patterns of the form /\bfoo/i didn't work right because the \b wants to compare the preceding character with the next one to look for word boundaries, and the i modifier forced a move of the string to a place where it couldn't do that without examining malloc garbage. The type glob syntax *foo produces the symbol table entry for all the various foo variables. Perl has to do certain bookkeeping when moving such values around. The symbol table entry was not adequately differentiated from normal data to prevent occasion confusion, however. On MICROPORTs, the CRIPPLED_CC option made the stab_array() and stab_hash() macros into function calls, but neglected to supply the function definitions. The string length allocated to turn a number into a string internally turned out to be too short on a Sun 4. Several constructs were not recognized properly inside double-quoted strings: underline in name required @foo to be defined rather than %foo threw off bracket matcher not identified with $1 The base.term test gives misleading results if /dev/null happens not to be a character special file. So it now checks for that. The op.stat could exceed the shell's maximum argument length when evaluating </usr/bin/*>. It now chdirs to /usr/bin and does <*>. return grandfathered to never be function call The construct return (1,2,3); did not do what was expected, since return was swallowing the parens in order to consider itself a function. The solution, since return never wants any trailing expression such as return (1,2,3) + 2; is to simply make return an exception to the paren-makes-a-function rule, and treat it the way it always was, so that it doesn't strip the parens. If perldb.pl doesn't exist, there was no reasonable error message given when you invoke perl -d. It now does a do-or-die internally. null hereis core dumped The hereis construct dumped core on a null string: print <<'FOO'; FOO Certain pattern matches weren't working on patterns with embedded nulls because the fbminstr() routine, when it decided it couldn't do a fancy search, degenerated to using instr(), rather than ninstr(), which is better about embedded nulls. The s2p sed-to-perl translator didn't translate \< and \> to \b. Now it does. The a2p awk-to-perl translator didn't put a $ on ExitValue when translating the awk exit construct. It also didn't allow logical expressions inside normal expressions: i = ($1 == 2 || $2 ~ /bar/) a2p.h had definition of a bzero() macro inside an ifdef of BCOPY. The two don't always go together, and since Configure is already looking for both separately...
* perl 3.0: (no announcement message available)perl-3.000Larry Wall1989-10-1831-51/+269
| | | | | | | | | | | | | | A few of the new features: (18 Oct) * Perl can now handle binary data correctly and has functions to pack and unpack binary structures into arrays or lists. You can now do arbitrary ioctl functions. * You can now pass things to subroutines by reference. * Debugger enhancements. * An array or associative array may now appear in a local() list. * Array values may now be interpolated into strings. * Subroutine names are now distinguished by prefixing with &. You can call subroutines without using do, and without passing any argument list at all. * You can use the new -u switch to cause perl to dump core so that you can run undump and produce a binary executable image. Alternately you can use the "dump" operator after initializing any variables and such. * You can now chop lists. * Perl now uses /bin/csh to do filename globbing, if available. This means that filenames with spaces or other strangenesses work right. * New functions: mkdir and rmdir, getppid, getpgrp and setpgrp, getpriority and setpriority, chroot, ioctl and fcntl, flock, readlink, lstat, rindex, pack and unpack, read, warn, dbmopen and dbmclose, dump, reverse, defined, undef.
* perl 2.0 (no announcement message available)perl-2.0Larry Wall1988-06-0528-0/+1477
Some of the enhancements from Perl1 included: * New regexp routines derived from Henry Spencer's. o Support for /(foo|bar)/. o Support for /(foo)*/ and /(foo)+/. o \s for whitespace, \S for non-, \d for digit, \D nondigit * Local variables in blocks, subroutines and evals. * Recursive subroutine calls are now supported. * Array values may now be interpolated into lists: unlink 'foo', 'bar', @trashcan, 'tmp'; * File globbing. * Use of <> in array contexts returns the whole file or glob list. * New iterator for normal arrays, foreach, that allows both read and write. * Ability to open pipe to a forked off script for secure pipes in setuid scripts. * File inclusion via do 'foo.pl'; * More file tests, including -t to see if, for instance, stdin is a terminal. File tests now behave in a more correct manner. You can do file tests on filehandles as well as filenames. The special filetests -T and -B test a file to see if it's text or binary. * An eof can now be used on each file of the <> input for such purposes as resetting the line numbers or appending to each file of an inplace edit. * Assignments can now function as lvalues, so you can say things like ($HOST = $host) =~ tr/a-z/A-Z/; ($obj = $src) =~ s/\.c$/.o/; * You can now do certain file operations with a variable which holds the name of a filehandle, e.g. open(++$incl,$includefilename); $foo = <$incl>; * Warnings are now available (with -w) on use of uninitialized variables and on identifiers that are mentioned only once, and on reference to various undefined things. * There is now a wait operator. * There is now a sort operator. * The manual is now not lying when it says that perl is generally faster than sed. I hope.