Editing PerlNomicPatches
This is a lesson on how to write a PerlNomic proposal which patches other files. This is important because (so far) much of the game consists of patching existing files, including both CGI scripts and proposals. (And sometimes other files, such as when RobAdams attemped to patch players.txt to remove himself from the game.) The easiest way to patch files is to use the UNIX "patch" utility (big surprise!) written by none other than LarryWall himself. (LarryWall is the same guy who wrote Perl.) Another useful thing is to use Perl's support for "HERE document" quoting. This is a method of quoting which allows one to include arbitrary text verbatim into a string in Perl. This makes it easy to quote Perl code (otherwise you'd have to worry about accidently interpolating variables, etc.) which is useful because the files you'll be patching are probably Perl programs. ----- An example of "HERE document" quoting: my $long_string = <<'END_OF_STRING'; This is the first line of the string. This is the second line of the string. I can include funny characters $@'"`[->blah and Perl won't care. END_OF_STRING Now the scalar $long_string contains four lines of text. Notice that the terminating string must occur on a line by itself. See the CamelBook or the perlop man page for more information. ----- '''Using the ''patch'' utility''' ''Patch'' works by taking the output of the ''diff'' utility and applying it to your files. There are all sorts of options and output formats for ''diff'' but we'll keep things simple here and only use one set of options. Patch supports several different file formats, but with varying levels of support. I suggest using the "unified context diff" format. It's only supported by the GNU versions of ''diff'' and ''patch'', but PerlNomic runs on Odin which is a Linux box. If you are developing your patches on a system with a non-GNU diff, then you may need to use a different format. See the ''diff'' and ''patch'' man pages and/or info pages for more information. ----- '''Generating your patch file''' Make a directory called "old" and put all of your files in it. Now make a directory called "new" and put copies of all your files in it. Modify the files in "new" so they have all the changes you want. Now run the following command from the parent directory: diff -Naur old new >> my.patch This will make diff look at the directories old and new and record any differences in the files contained in the directories. It will write all of these differences to standard out, which you have redirected into the file my.patch. (obviously, you can change the name if you want.) Take a look at the file my.patch to make sure it's doing what you want. The unified context diff format is pretty easy to figure out. Lines starting with "-" are being removed, and lines which start with "+" are being added. I strongly recommend that you always use this old/new directory approach when making diffs. It's easier to keep things straight, plus it means that you'll always use the same "-p" option to ''patch'' (see below). ----- '''Creating your Perl script''' Create a new file in your favorite text editor. Put the following into it: #!/usr/bin/perl # # Description of what my patch does # # Author: my name # Date: today's date # open (PATCH, "|patch -p1"); print PATCH <<'__END__OF__PATCH__'; __END__OF__PATCH__ close PATCH; Now paste the contents of my.patch (or whatever you called it) between the "print" line and the "__END__OF__PATCH__" line. Make sure you don't add or delete any lines by accident! (if your patch file has some blank lines at the end, make sure to leave them there when you paste. You want the '''EXACT''' contents of the patch file to be contained there! This is your PerlNomic proposal. Upload it to PerlNomic. Be very careful when pasting it into the form. (Perhaps the form should be modified to allow file uploads.. recent versions of HTML support this) '''How it works''' The "open" line forks off a ''patch'' process and sets up a pipe into it. The "-p1" option causes ''patch'' to ignore the first directory name in pathnames. (So it won't start looking for directories called "old" or "new".. instead it will strip off the directory name and look for the files in the current directory.) The "print" statement writes the patch to the pipe. The ''patch'' process reads in the patch and patches the files. You can put additional Perl code before the "open" line or after the "close" line if you need to do other stuff in addition to patching files. ----- Future additions for this guide: * Guide to writing patches which patch proposals containing patches .. a real mind bending exercise.. not to be done unless you really know what you're doing.. and it may give you a headache! ** Hopefully, there should no longer be a need for this. If you find a bug in your own proposal,\ rescind it and submit the improved version. If you find a bug in someone else's, let everyone \ know, and submit your own improved version. --AdamBliss
Summary:
This change is a minor edit.
(Visit
Preferences
to set your user name.)