tag:blogger.com,1999:blog-42060984383263344822024-03-05T04:06:17.204-05:00SvOK(get_sv("main::blog", 0));Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.comBlogger36125tag:blogger.com,1999:blog-4206098438326334482.post-43374365744531453762013-02-18T18:17:00.000-05:002013-02-19T15:34:03.405-05:00Just add a spaceSo, the thing to do these days seems to be to comment on the idea of renaming (or not renaming) Perl. My gut instinct is that it will do no good and possibly do harm. If I saw a project I had thought was stagnated rename itself with a lot of fanfare and then went and looked at it and found it was in the same state as before, then I would worry about the competence of the people running the project. That said, I think there is definitely a way to have our cake and eat it too here:<br />
<span style="font-size: x-large;"><br /></span>
<span style="font-size: x-large;">All we have to do is add a space.</span><br />
<br />
Just add a space to Perl 5.X.X to get Perl 5 X.X. Our language is Perl 5. We should own that fact. Yeah, there is another language named Perl 6 that might be better (if it is every finished) and one named Perl 4 that is worse. We are currently on version 16.2 of Perl 5. Our version number is now significantly more than 6, which lets the people who want to rename Perl to get people to stop paying attention to the fact the Perl 6 is still not production ready to have a version greater than 6 while not confusing the issue.<br />
<br />
And while we are at it, let's sit down with Ubuntu and Red Hat and come up with a way to package Perl 5 that suits both us and them. Something that makes their life easier and encourages them to release newer versions of Perl 5, while, at the same time, fits our needs as developers.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com1tag:blogger.com,1999:blog-4206098438326334482.post-90878378917225048112010-09-02T12:24:00.000-04:002010-09-02T12:25:20.220-04:00I need a few lines of nasty Perl 5 code.I am writing a talk for beginning Perl 5 programmers covering how to read a line of code and I need a few nasty lines that are fairly self contained. These should be normal lines of code (no obfuscation), they just need to have a lot going on in them. Things involving multiple <code>map</code>s with complex bodies would be good. If you have one or more such beasts, would you leave a comment with them?<br /><br />The talk will be given at <a href="http://pghpw.org/ppw2010/">The Pittsburgh Perl Workshop</a>.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com2tag:blogger.com,1999:blog-4206098438326334482.post-5462164327015633042010-07-14T08:06:00.002-04:002010-07-14T08:11:14.283-04:00Adventures in Ignorance: Autovivification for fun and profit<p>Perl 5 autovivifies hashes and arrays when an undef is used as a hashref or arrayref. Normally you see this when using multidimensional data structures like this:<pre>my %hash;<br />$hash{foo}{bar} = 1;</pre><p>The value in <code>$hash{foo}</code> is undefined, so Perl 5 turns it into a hashref so it can lookup the key <code>"bar"</code> in it. This is somewhat dangerous because you can create keys without meaning to:<pre>if ($hash{bar}{baz} == 1) {<br /> say "found "bar/baz";<br />}</pre><p>Here the key <code>"bar"</code> will be added to the <code>%hash</code> if it doesn't already exist. To prevent this we must check every level but the last with <a href="http://perldoc.perl.org/functions/exists.html"><code>exists</code></a>:<pre>if (exists $hash{bar} and $hash{bar}{baz} == 1) {<br /> say "found "bar/baz";<br />}</pre><p>When I think of autovivification, that is all I normally think of, but today I realized you can use it for more than that. I have a couple of hashrefs I want to set the initial size of with <a href="http://perldoc.perl.org/functions/keys.html"><code>keys</code></a>. I was saying<pre>my $hashref = {};<br />keys(%$hashref) = 1024;</pre><p>As I wrote that I wondered if autovivification would turn an <code>undef</code> in $hashref into a hashref for me, and sure enough it will:<pre>#!/usr/bin/perl<br /><br />use 5.012;<br />use warnings;<br /><br />use Scalar::Util qw/reftype/;<br /><br />my $hashref; #not really a hashref yet<br />keys(%$hashref) = 1024; #but now it is<br /><br />say reftype $hashref;</pre>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-12299616199699659182010-07-09T09:22:00.008-04:002010-07-09T10:01:34.278-04:00Adventures in Ignorance: when both Perl and the Developer are too smart for their own good.<p>So, <a href="http://perldoc.perl.org/functions/split.html"><code>split<code></a> returns the number of fields it would have split into when called in scalar context, but it also throws a warning in Perl 5.10: <code>"Use of implicit split to @_ is deprecated"</code>. In an attempt to placate the warning I wrote</p><pre>my $count =()= split $delim, $string;</pre><p>but was surprised to find that every string returned <code>1</code>. This is due to a nice little optimization that <code>split</code> does for you:<blockquote>When assigning to a list, if LIMIT is omitted, or zero, Perl<br />supplies a LIMIT one larger than the number of variables in the<br />list, to avoid unnecessary work. For the list above LIMIT<br />would have been 4 by default. In time critical applications it<br />behooves you not to split into more fields than you really<br />need.</blockquote>To get around this you must specify your own limit of <code>-1</code>:</p><pre>my $count =()= split $delim, $string, -1;</pre><p>Of course, <code>-1</code> doesn't have the same behavior as no limit or a limit of <code>0</code> (a limit of <code>-1</code> preserves empty trailing fields), so this is not necessarily what you want. This leaves us with the last line of defense, turning off warnings (and it isn't pretty):</p><pre>my $count = do {<br /> no warnings "deprecated";<br /> split $delim, $second;<br />};</pre>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com6tag:blogger.com,1999:blog-4206098438326334482.post-50771648942661816582010-07-01T13:15:00.000-04:002010-07-01T13:16:11.103-04:00Announcing the Perl 5 Documentation Team<p>I am excited to announce the formation of the Perl 5 Documentation Team. Our goal is to have the best, most current, and easiest to use and understand documentation of any programming language. Why settle for small goals?</p> <p>Since the success of this team will depend on having both expert and novice points of view, membership is open to all, regardless of experience level with Perl. This is an excellent opportunity for people who would like to make a contribution back to the Perl community to do so in a way that doesn't require expert programming abilities.</p> <p>If you are interested in being part of the team, please subscribe to <a href="http://lists.perl.org/list/perl-documentation.html">the Perl Documentation mailing list</a>, as future discussion will occur there (look for the thread named "I want to sign up"). If you know of other people who may be interested in being part of this effort, please pass this message on to them. </p> <p>Areas where the team will be active include:</p> <ul> <li>Reviewing and updating documentation to ensure that it is friendly to new users</li> <li>Updating examples in documentation to a style compatible with Modern Perl practices</li> <li>Updating the documentation so that all examples longer than one line contain a <code>use</code> statement indicating the minimum version of Perl 5 required to run the example</li> <li>Monitoring <a href="http://lists.perl.org/list/perl5-porters.html">p5p</a> for incoming documentation patches, ensuring they contain a patch against the current delta, and forwarding them to committers as needed</li> <li>Monitoring p5p for patches that will require modification of documentation, and ensuring that the documentation is modified appropriately</li> <li>Verifying that perlglossary contains current accurate definitions for all jargon terms</li> </ul> <p>Goals to be met for the Perl 5.14.0 release include:</p> <ul> <li>Recruit novice and experienced Perl programmers to the team, and create a Perl module (a la Perl::Staff) and a Perl 5 wiki entry listing the team members</li> <li>Finalize <a href="http://github.com/cowens/perlopquick">perlopquick</a> as a replacement for perlop and modify the new perlop so that perlop and a shorter perlopref can be generated from a single source document</li> <li>Extend perldoc to use the new perlop to provide documentation on operators (tenative proposal: perldoc -O "^=")</li> <li>Create a perlfuncref, a series of short summaries of information in perlfunc, analogous to perlopref (Again, both of these will be generated from a single source document for ease of maintenance)</li> <li>Define a policy for documenting documentation changes in the Perl deltas (e.g. perl5133delta.pod)</li> <li>Define a set of documentation style guidelines, covering structure, style, and content</li> <li>Formally define the Perl 5 Documentation Team functions</li> <li>Set deadlines for the defining of longer term goals</li> <li>Create a logo for the Perl 5 Documentation Team</li> <li>Find a better name or nickname for the Perl 5 Documentation Team</li> </ul> <p>Potential longer term (post-5.14.0) goals:</p> <ul> <li>Clean up perlre</li> <li>Extensive review and Modernization of all examples</li> <li>Develop a plan to integrate with the <a href="http://pod2.perl.org/">Pod2 translation project</a></li> </ul>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com5tag:blogger.com,1999:blog-4206098438326334482.post-62106897856645885712010-03-03T07:47:00.002-05:002010-03-03T14:27:01.060-05:00Parts of Perl you never knew existedThis is a list of some of the darker, scarier, or lesser known areas of Perl. I am going to be grouping them into a set of talks to scare, disgust, and delight the <a href="http://dc.pm.org">DC Perl Mongers</a>. There is no ordering to them In this post; I am just trying to start a list of talk items.<br /><br /><ul><li>Prototypes</li><li>what happens when you add a & to the start of a function call (aka why you shouldn't)</li><li>split in void context</li><li>goto function</li><li>values vs variables (a superset of lists vs arrays)</li><li>wantarray and contexts (void, scalar, list) </li><li>pseudohashes</li><li>tie</li><li>typeglobs</li><li>PadWalker</li><li>source filters</li><li>adding methods to existing classes</li><li>interpolating things that aren't scalars or arrays</li><li>when to use each vs keys</li><li>warnings <ul><li>how to disable certain warnings without affecting other warnings</li><li>how to add categories</li></ul></li><li>B::Deparse, showing the magic Perl does for you <ul><li>while (<>), while (readline), and while(readdir)</li><li>default values for split, print, etc.</li></ul></li><li>do file</li><li><a href="http://svok.blogspot.com/2009/09/adventures-in-ignorance-what-i-have.html">weird operators</a></li><li>special variables <ul><li>%main::</li><li>$]</li><li>$"</li><li>$,</li><li>$/ and $\</li><li>%SIG</li></ul></li><li>what strict does and why <ul><li>symbolic references</li><li>barewords</li></ul></li><li>regex magic <ul><li>\k</li><li>\g</li><li>\G</li><li>\Q</li><li>differences between scalar and list context</li><li>recursion</li></ul></li></ul>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com5tag:blogger.com,1999:blog-4206098438326334482.post-54453407888120197592009-10-20T17:25:00.003-04:002009-10-20T17:48:34.659-04:00Day six with Google WaveWell, I am starting to get a real understanding of why they made the UI decisions that seemed weird at first. I am even considering reading the specs and seeing if I get talk to their implementation of the server with my own client (to get things like <a href="http://growl.info/">growl</a>/<a href="http://www.galago-project.org/news/index.php">libnotify</a> notifications working).<br /><br />On the browser side, it seems to work best with Google Chrome. This is not a big shock. It doesn't seem as memory hungry with Google Chrome (63 MB vs 200 MB in Safari or Firefox on the first page), but it does seem to grow in size over time as I access waves (102 MB after accessing 10 waves). Another nice thing about Chrome is its model for tabs. Each runs in its own process, so killing a tab frees all of the memory associated with it. This means that when it starts eating too much memory, I can simply start a new Google Wave tab and close the old one instead of having to shutdown the whole application (which is what I have resorted to with Firefox and Safari). The downside is that Google Chrome has not been released for OS X. Luckily there is a <a href="http://dev.chromium.org/getting-involved/dev-channel">developer version</a> available for Linux and OS X (which is what I have been running).Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com1tag:blogger.com,1999:blog-4206098438326334482.post-13425619775523672972009-10-15T10:23:00.003-04:002009-10-15T11:01:38.665-04:00Google Wave day twoI have finally had an IM-like exchange with one of my friends. It is confusing to say the least. Should I start a new blip after each exchange? Should I modify my blip in response to the other one instead? Should I clean the exchange up for others on the Wave? I figure social rules will develop similar to how bottom vs top vs inline rules developed for email; of course, that means we are in for another round of religious debates and flames.<br /><br />The idea of flames brings up another thought. What will flames look like when you can edit not only your own messages, but other's messages as well? Google Wave needs a reputation system of some form. One that weights a person's reputation based on the opinion's of people you already trust. It also needs a way to control who can see a wave vs who can edit it. There are already read-only waves, but <a href="http://www.google.com/support/wave/bin/answer.py?hl=en&answer=163150">only the system can create them</a>. I think it might become important for blips to be marked read-only, or writable only by a specific subset of the wave participants.<br /><br />As for the memory issue I mentioned yesterday, it isn't so bad if I stay away from Waves that have many blips. Firefox (on OS X) is eating about 300 MB, which is up from the 100 MB it normally eats, but it has not yet exploded to the 1 GB mark like it did yesterday.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-91773124252785025302009-10-14T08:25:00.003-04:002009-10-14T09:15:19.361-04:00Day one with Google WaveSo I got a <a href="http://wave.google.com">Google Wave</a> invite yesterday morning and immediately signed up. The interface is nice, if a bit slow at times on my 2.16 GHz MacBook Pro with 2 GB of RAM. It also ate 1 GB at one point and Firefox started acting weirdly (left clicks on flash apps were generating right click behavior). Firefox normally eats around 100 MB of RAM on my machine, but right now with Google Wave open, and having only worked with two waves, it is eating 300 MB.<br /><br />If have mostly used it like email so far, I haven't had a chance to play with the IM like features. I have used the wiki-like editing feature though, replayed the history of a couple of waves, and used the map gadget and everything worked pretty much the way I expected it to. I played a little with the <a href="http://wave-samples-gallery.appspot.com/about_app?app_id=14008">kasyntaxy</a> bot and it was interesting, but its Perl syntax highlighting leaves a lot to be desired.<br /><br />If you are on Google Wave as well, drop me a line at chas.owens.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-2161363143880566822009-10-12T12:36:00.002-04:002009-10-12T13:01:03.946-04:00A blogger gadget for IronmanSo, since my badge is now working, I thought it would be a good idea to add my badge to my blog. It turned out to be fairly simple, and if you are using blogger, you can just reuse my work. All you need to do is<ol><li>Click "Customize"</li><li>Click "Add a Gadget"</li><li>Click "Add your own"</li><li>enter the URL <code>http://wonkden.net/ironman_perl_gadget.xml</code></li><li>Click "ADD BY URL"</li><li>Set the background color</li><li>Set the name you <a href="http://ironman.enlightenedperl.org/munger/mybadge/male/">registered</a> with the Ironman competition</li><li>Set the sex of your badge</li><li>And, finally, click "Save"</li></ol>Just for the record, here is the XML used to create the gadget:<pre><?xml version="1.0" encoding="UTF-8" ?> <br /><Module><br /> <ModulePrefs<br /> title = "Ironman Perl Gadget"<br /> title_url = "http://wonkden.net/ironman_perl_gadget.xml" <br /> height = "80" <br /> author = "Chas. Owens" <br /> author_email = "chas.owens@gmail.com"<br /> /> <br /> <UserPref<br /> name = "bg"<br /> display_name = "Background Color"<br /> datatype = "string"<br /> required = "true"<br /> /><br /> <UserPref<br /> name = "ironman-name"<br /> display_name = "Ironman Perl name"<br /> datatype = "string"<br /> required = "true"<br /> /><br /> <UserPref<br /> name = "ironman-sex"<br /> display_name = "Sex"<br /> datatype = "enum"<br /> required = "true"<br /> ><br /> <EnumValue value="male" display_value="Male"/><br /> <EnumValue value="female" display_value="Female"/><br /> </UserPref><br /><br /> <Content type="html"><br /> <![CDATA[<br /> <script type="text/javascript"><br /> var prefs = new _IG_Prefs();<br /> var name = prefs.getString("ironman-name");<br /> var sex = prefs.getString("ironman-sex"); <br /> var color = prefs.getString("bg"); <br /> var html = '<div align="center" style="background-color: ' + color + '"><img src="http://ironman.enlightenedperl.org/munger/mybadge/' + sex + '/' + name + '.png" alt="Ironman Perl badge for ' + name + '"></div>'<br /><br /> document.write(html);<br /> </script> <br /> ]]><br /> </Content> <br /></Module></pre>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-17382967466491070252009-10-12T08:52:00.005-04:002009-10-12T10:24:30.316-04:00Should PERL_UNICODE be considered harmful?I set <code>PERL_UNICODE</code> to <code>"SDL"</code> as a matter of course when setting up my environment. This means that all of my filehandles will use the UTF-8 PerlIO layer unless the locale says otherwise or a specific layer is chosen explicitly. I do this because I don't want to have to worry about calling <a href="http://perldoc.perl.org/functions/binmode.html"><code>binmode</code></a> or explicitly setting the PerlIO layer when opening a file:<pre>open my $fh, "<:utf8", $filename<br /> or die "could not open $filename: $!"</pre>This has worked fine for me for years; however, recently I have noticed a few problems with it:<br /><ul><li>You cannot compile Perl will it set</li><li>Many modules fail their tests when it is set</li><li>Scripts that work just fine in your environment fail in other environments</li><li>since it affects all filehandles, it could cause bugs in modules (I have never actually seen this)</li></ul>Given these issues, I am starting to consider PERL_UNICODE harmful and thinking about giving it up.<br /><br />Does anyone know of any arguments to keep using it, or, conversely, more arguments to stop using it?Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com2tag:blogger.com,1999:blog-4206098438326334482.post-18320652423902395432009-10-05T08:54:00.004-04:002009-10-05T09:12:18.641-04:00Yay! my badge works, Boo! no time for Perl<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://ironman.enlightenedperl.org/munger/badges/male/bronze.png"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 50px; height: 80px;" src="http://ironman.enlightenedperl.org/munger/badges/male/bronze.png" border="0" alt="" /></a>Yay! I am a bronze man. Also, all of my projects either on hold or are going to progress very slowly for the next few months. My wife has been in and out of the hospital for the last few months, the last time via an ambulance. I have been force to make lifestyle changes such as fixed times to go to bed at night (2200 ET versus somewhere between 2000 ET and 0600 ET) and get up in the morning (0630 ET vs somewhere between 0900 ET and 1100 ET) and the careful cooking of all of our meals (did you know there was a meal called breakfast that didn't entail just grabbing a soda on the way out the door?), so I don't have nearly as much discretionary time as I once did. Hopefully in a couple months she will be strong enough to start helping with things again and I will get some time back for Perl.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com2tag:blogger.com,1999:blog-4206098438326334482.post-48869644939140299532009-09-28T09:15:00.002-04:002009-09-28T09:24:20.008-04:00perlopref needs youThe <a href="http://github.com/cowens/perlopref">perlopref document</a> is nearing completion. I need to add the file test, quote-like, regex quote-like, and I/O operators, but now is a good time for other people to go over the document and make sure I haven't made any mistakes or omissions.<br /><br />I am also thinking about changing the name to perlopquick since it isn't really a reference (it doesn't contain everything about the operators).Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-67321720388748352802009-09-20T23:19:00.000-04:002009-09-20T23:20:58.850-04:00giving some love to doThe <code>do {}</code> construct does not get much love in most of the code I see. Besides <code>do {} while</code> loops, it is very useful for combining steps and limiting the scope of variables:<pre>my $contents = do {<br /> local $/;<br /> open my $fh, "<", $filename<br /> or die "could not open $filename: $!";<br /> <$fh>;<br />};</pre>The snippet above keeps the change to <code>$/</code> and the <code>$fh</code> variable local to the section that needs it.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com2tag:blogger.com,1999:blog-4206098438326334482.post-27206461266379470292009-09-13T15:50:00.002-04:002009-09-13T15:52:10.008-04:00adventures in ignorance: what I have learned from perlopref so farWhile working on <a href="http://github.com/cowens/perlopref">perlopref</a> I have learned a few things about Perl I had never known. This is a short list of the things I learned (besides the bit about <a href="http://svok.blogspot.com/2009/08/adventures-in-ignorance-modulo-operator.html">modulo</a> that I have already blog'ed about).<br /><hr>Only the plain assignment operator (<code>=</code>) can do list assignment. I found this out when I expected <code>@a x= 5</code> to do something (besides throw an error that is). This makes sense for most of the assignment operators. For instance, <code>@x += 2</code> makes very little sense, but I think <code>@a x= 3</code> makes some sense, but alas it is an error.<br /><hr>The bitwise and operator (<code>&</code>) has different behavior with respect to strings than the bitwise or and xor operators (<code>|</code> and <code>^</code> respectively). Bitwise and truncates to the length of the shorter string, but bitwise or and xor extend the shorter string to the length of the longer one with nul characters.<br /><hr>The arrow operator has surprising behavior with respect to coderefs. This code throws an error as I would expect:<pre>#!/usr/bin/perl<br /><br />use strict;<br />use warnings;<br /><br />sub func {<br /> return [qw/a b c/];<br />}<br /><br />print func()[0], "\n";</pre>But this code prints <code>"a\n"</code>:<pre>#!/usr/bin/perl<br /><br />use strict;<br />use warnings;<br /><br />sub func {<br /> return [qw/a b c/];<br />}<br /><br />my $ref = \&func;<br /><br />print $ref->()[0], "\n";</pre>This seems to be an extension of the rule that lets you pretend that an AoA is really a multi-dimensional array. I knew this rule allowed you to say <code>$aoa->[0][1]("arg1", "arg2")</code>, but I had never tried it with the function call first.<br /><hr>Some people use <code>~~X</code> (i.e. <code>~(~X)</code>) to force scalar context on <code>X</code>, boy are they going to be annoyed by the smartmatch operator.<br /><hr>I go through bouts of knowing and forgetting this, but the flip-flop operators (<code>..</code> and <code>...</code>) actually return useful information, not just true or false:<pre>#!/usr/bin/perl<br /><br />use strict;<br />use warnings;<br /><br />for my $i (1 .. 10) {<br /> my $range = ($i == 2 or $i == 6) .. ($i == 4 or $i == 8);<br /> print "$range: $i\n" if $range;<br />}</pre>The code above prints<pre>1: 2<br />2: 3<br />3E0: 4<br />1: 6<br />2: 7<br />3E0: 8</pre><hr>The comparison operators (<code><=></code> and <code>cmp</code>) return <code>-1</code>, <code>0</code>, and <code>1</code> not negative, zero, and positive. I had always though it wasn't guaranteed what the return value was, but apparently it is.<br /><hr>Perl 5.10.1 does not have the <code>err</code> operator (i.e. the low precedence version of <code>//</code>. I could have sworn it did, but it is not there. It looks like I am not the only one confused by its non-existence though, <code>perlop</code> has a section titled <a href="http://perldoc.perl.org/perlop.html#Logical-or,-Defined-or,-and-Exclusive-Or">"Logical or, Defined or, and Exclusive Or"</a> that only describes <code>or</code> and <code>xor</code>.<br /><hr>The left bit shift operator (<code><<</code>) is not defined if you you shift past the boundary of your native integer. I had always assumed that it dropped those bits, but apparently that is just the behavior of the versions of C I have used in the past (ANSI/ISO C does not define the behavior of overflow due to shifting, so it is a crap shoot).<br /><hr>The <code>and</code> and <code>or</code> operators have different precedence levels. The <code>and</code> operator binds more tightly than <code>or</code>, so<pre>$x == 5 and $y == 6 or $x == 6 and $y == 5</pre>is the same as<pre>(($x == 5) and ($y == 6)) or (($x == 6) and ($y == 5))</pre>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com2tag:blogger.com,1999:blog-4206098438326334482.post-67330589077309151862009-09-12T15:31:00.001-04:002009-09-12T15:32:48.665-04:00Adding house policies to Perl::Critic.Recently on <a href="http://stackoverflow.com/questions/1378764">Stack Overflow</a>, someone want code that could either modify Perl source code to remove comments that where on the same line as code, or warn him that comments were on the same line as code. Apparently he had a house style that needed to be enforced. I decided a <a href="http://search.cpan.org/dist/Perl-Critic/lib/Perl/Critic.pm"><code>Perl::Critic</code></a> policy to warn him of the style violation was the way to go. I spent about fifteen minutes looking at the docs and writing code and I came up with this:<pre>package Perl::Critic::Policy::CodeLayout::NoSideComments;<br /><br />use strict;<br />use warnings;<br /><br />use Readonly;<br /><br />use Perl::Critic::Utils qw{ :severities :classification :ppi };<br />use parent 'Perl::Critic::Policy';<br /><br />our $VERSION = 20090904;<br /><br />Readonly::Scalar my $DESC => "side comments are not allowed";<br />Readonly::Scalar my $EXPL => "put the comment above the line, not next to it";<br /><br />sub supported_parameters { return }<br />sub default_severity { return 5 }<br />sub default_themes { return qw( custom ) }<br />sub applies_to { return 'PPI::Token::Comment' }<br /><br />sub violates {<br /> my ($self, $elem) = @_;<br /><br /> #look backwards until you find whitespace that contains a <br /> #newline (good) or something other than whitespace (error)<br /><br /> my $prev = $elem->previous_sibling;<br /> while ($prev) {<br /> return $self->violation( $DESC, $EXPL, $elem )<br /> unless $prev->isa("PPI::Token::Whitespace");<br /> return if $prev->content =~ /\n/;<br /> $prev = $prev->previous_sibling;<br /> }<br /><br /> #catch # after a block start, but leave the #! line alone<br /> return $self->violation( $DESC, $EXPL, $elem )<br /> unless $elem->parent->isa("PPI::Document");<br /> return;<br />}<br /><br />1;</pre>I was surprised at just how easy <a href="http://search.cpan.org/dist/PPI/lib/PPI.pm"><code>PPI</code></a> and <code>Perl::Critic</code> makes this.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-16178857162461675082009-09-12T14:53:00.002-04:002009-09-12T14:56:35.499-04:00Announcing perlcolorSo, recently on the Perl Beginners list there was some discussion about the <a href="http://www.nntp.perl.org/group/perl.beginners/2009/09/msg109008.html">merits and flaws of documentation that comes with Perl</a>. At one point Raymond Wan said<blockquote>Perldoc is somewhat hard to get into...but it's the manual for a programming language, so that's expected; I don't think having pages to color and draw on would be a feasible idea for the next update. :-)</blockquote>I immediately disagreed. I think it is a fine idea and began work on such a document. At first it was simply a joke, but I am beginning to think that it might actually be a very good, light-hearted, introduction to Perl concepts such as CPAN, reporting bugs, etc. As with just about everything I do, I have put it up on GitHub. <a href="http://github.com/cowens/perlcolor">Fork</a> it and add to it.<br /><br /><tt>=head1 NAME<br /><br />perlcolor - coloring book for new perlers<br /><br />=head1 IMAGES<br /><br />=head2 Camels and Llamas<br /><br />Camels in connection with Perl are a trademark of O'Reilly Media. O'Reilly<br />publishes many of the most important Perl books such as Programming Perl (aka the Camel) and Learning Perl (aka the Llama). Have you read them?<br /><br /><pre> _<br /> .--' |<br /> /___^ | .--.<br /> ) | / \<br /> / | /` '.<br /> | '-' / \<br /> \ | |\<br /> \ / \ /\|<br /> \ /'----`\ /<br /> || \ |<br /> (| (|<br /> || ||<br /> jgs /_( /_(<br /><br /> _ _<br /> ( \__//) <br /> .' )<br /> __/b d . )<br /> (_Y_`, .)<br /> `--'-,-' )<br /> (. )<br /> ( )<br /> ( )<br /> ( . ) .---.<br /> ( ) ( )<br /> ( . ) ( . )<br /> ( ) ( . ),<br /> ( . `"'` . `)\<br /> ( . .)\<br /> (( . . ( . )\\<br /> (( . ( ) \\<br /> (( ) _( . . ) \\<br /> ( ( . )"'"`(.( ) ( ;<br /> ( ( ) ( ( . ) \'<br /> |~( ) |~( )<br /> | ||~| | ||~|<br /> jgs | || | | || | <br /> _| || | _| || |<br /> /___(| | /___(| |<br /> /___( /___(</pre><br /><br />=head2 Monkeys<br /><br />In the end we are all code monkeys. Code, code monkeys, code!<br /><br /><pre> .="=.<br /> _/.-.-.\_ _<br /> ( ( o o ) ) ))<br /> |/ " \| //<br /> .-------. \'---'/ //<br /> _|~~ ~~ |_ /`"""`\\ ((<br /> =(_|_______|_)= / /_,_\ \\ \\<br /> |:::::::::| \_\\_'__/ \ ))<br /> |:::::::[]| /` /`~\ |//<br /> |o=======.| / / \ /<br /> jgs `"""""""""` ,--`,--'\/\ /<br /> '-- "--' '--'</pre><br /><br />=head2 Butterflies<br /><br />Camelia is a butterfly. She is the Perl 6 mascot. Can you find the hidden<br />P6?<br /><br /><pre> _ _<br /> / `._ _.' \<br /> ( @ : `. .' : @ )<br /> \ `. `. ._ _. .' .' /<br /> \;' P. `. \ / .' 6' `;/<br /> \`. `. \ \_/ / .' .'/<br /> ) :-._`. \ (:) / .'_.-: (<br /> (`.....,`.\/:\/.',.....')<br /> >------._|:::|_.------<<br /> / .'._>_.-|:::|-._<_.'. \<br /> |o _.-'_.-^|:|^-._`-._ o|<br /> |`' ;_.-'|:|`-._; `'|<br /> jgs ".o_.-' ;."|:|".; `-._o." <br /> ".__." \:/ ".__."<br /> ^</pre><br />=head2 Bugs<br /><br />Bugs are errors in code. Sometimes the bug is in Perl, but most of the time<br />the bug is your code. If you think the bug is in someone else's code, you<br />should report it to them. CPAN has a link for reporting bugs on each<br />module's page. Have you ever found a bug?<br /><br /><pre> ,_ _,<br /> '.__.'<br /> '-, (__) ,-'<br /> '._ .::. _.'<br /> _'(^^)'_<br /> _,` `>\/<` `,_<br /> ` ,-` )( `-, `<br /> | /==\ |<br /> ,-' |=-| '-,<br /> )-=(<br /> jgs \__/</pre><br /><br /><br />=head2 Penguins<br /><br />This is Tux. He is the Linux mascot. Linux is an important platform for<br />Perl. Linux comes in many flavors: Redhat, Ubuntu, SUSE, and many others.<br />Do you run Linux?<br /><pre> ___<br /> ,-' '-.<br /> / _ _ \<br /> | (o)_(o) |<br /> \ .-""-. /<br /> //`._.-'`\\<br /> // : ; \<br /> //. - '' -.| |<br /> /: : | |<br /> | | : ,/ /,<br /> jgs _;'`-, ' |`.-' `\<br /> ) `\.___./; .'<br /> '.__ )----'\__.-'<br /> `""`</pre><br /><br />=head2 Daemons<br /><br />This is the BSD Daemon. His name is Beastie. BSD is an important platform<br />for Perl. FreeBSD, NetBSD, OS X, and others are all variants of BSD. Do<br />you run a BSD variant? <br /><br /><pre> , , <br /> /( )` <br /> \ \___ / | <br /> /- _ `-/ ' <br /> (/\/ \ \ /\ <br /> / / | ` \ <br /> O O ) / | <br /> `-^--'`< ' <br /> (_.) _ ) / <br /> `.___/` / <br /> `-----' / <br /> <----. __ / __ \ <br /> <----|====O)))==) \) /==== <br /> <----' `--' `.__,' \ <br /> | | <br /> \ / /\<br /> ______( (_ / \______/ <br /> ,' ,-----' | <br /> `--{__________)</pre><br /><br />=head2 Strawberries<br /><br />Strawberry Perl is a version of Perl for Microsoft Windows. It comes with<br />its own build environment to make installing Perl modules from CPAN easy.<br />Have you every installed a Perl module from CPAN?<br /> <br /><pre> VVVVVVVV <br /> 'oOOOOOOOOo'<br /> 'ooOOOOOOoo'<br /> 'oooOOooo' <br /> 'oooooo'<br /> 'oooo'</pre><br /> <br /><br />=head2 Shebang<br /><br />The shebang line is what tells the OS the path to Perl. What is the path to<br />your Perl?<br /><br /><pre> # # # # !! !!<br /> # # # # !! !!<br /> # # # # !! !!<br /> #### #### #### !! !!<br /> !! !!<br /> #### #### #### !! !!<br /> # # # # !! !!<br /> # # # # !! !!<br /> # # # # !! !!<br /> #### #### #### !! !!<br /> <br /> #### #### #### <br /> # # # # !! !!<br /> # # # # !! !!<br /> # # # # !! !!</pre><br /><br />=head1 TODO<br /><br />We need a good ASCII art version of Hexley (the Darwin Mascot).<br /><br />My strawberry is terrible.<br /><br />=head1 LICENSE<br /><br />The BSD Daemon appears to be public domain. The strawberry and the #! are<br />released under the same terms as Perl. The rest of the ASCII art came from<br />L<http://www.geocities.com/soho/7373/index.html>.</tt>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com3tag:blogger.com,1999:blog-4206098438326334482.post-60734790519600153052009-09-07T01:31:00.000-04:002009-09-07T01:32:43.937-04:00What to call the ... operator?What should we call Perl 5's <a href="http://perldoc.perl.org/perlop.html#Range-Operators"><code>...</code> operator</a>? In list context it is identical to the range operator (<code>..</code>) and in scalar context it is almost identical to the flip-flop operator (also <code>..</code>). The Camel and <a href="http://perldoc.perl.org/perlop.html">perlop</a> are strangely silent on this. I am currently calling it the alternate range/flip-flop operator for lack of a better term. What do you call it?Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com3tag:blogger.com,1999:blog-4206098438326334482.post-42199252289866476322009-08-30T01:23:00.003-04:002009-08-30T01:34:38.987-04:00meta: no time to write what I want! badges! brokeness!Well, it has been eight days and I am pushing the limit of staying in the competition (or at least not resetting the clock). There are a few things I want to write, but don't have the time to pay attention to right now. Quick list of posts I want to write so I don't forget them:<br /><ul><li>simple parsing</li><li>shared memory (IPC and persistence)</li><li>dealing with Unicode combining characters (needs more research)</li></ul>In other news, the <a href="http://www.shadowcat.co.uk/blog/matt-s-trout/iron-munger-up/">Perl Ironman Badges</a> are up finally, but sadly my name seems to be breaking it. I can find a Chas and an Owens badge, but not a Chas. Owens badge. Also, I am showing up as a paperman in both which is either a bug in its calculation or mine.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-5349319638643047722009-08-22T22:27:00.001-04:002009-08-22T22:29:01.563-04:00Projects in progress as of 2009-08-22Unicode::Digits (<a href="http://github.com/cowens/Unicode-Digits">GitHub</a>, <a href="http://search.cpan.org/dist/Unicode-Digits/">CPAN</a>)<br /><br /><div class="subp">A test is failing on Perl 5.8. This is due to the test using a character that is a digit in Perl 5.10, but not in Perl 5.8. I need to fix this problem.</div><br /><div class="subp">I also want to add a function that will <a href="http://stackoverflow.com/questions/1182933">return a regex that can match a given digit or digits</a> (i.e. it should be able to match <code>"42"</code>, <code>"𝟜𝟚"</code>, or <code>"᠔᠒"</code>), but I am still not certain how the interface should work. For instance, should it only allow single digits (forcing the user to build more complicated regexes?<pre>my $one = digit_one();</pre>Should it take a string and replace the digits and character classes with the expanded character classes?<pre>my $re = digit_regex "This matches 42";</pre>Should it be OO based and let you chose specific sets of digits?<pre>my $ud = Unicode::Digit->new(<br /> "ASCII", #special case, "" looks stupid<br /> "MATHEMATICAL DOUBLE-STRUCK",<br /> "MONGOLIAN"<br />);<br />my $re = $ud->digit_regex("[1-3]");</pre>I am leaning toward the last one. And I am leaning toward only allowing a small subset of regex-like syntax (basically numbers and character classes containing numbers or ranges only).</div><br />autobox::dump (<a href="http://github.com/cowens/autobox-dump">GitHub</a>, <a href="http://search.cpan.org/dist/autobox-dump/">CPAN</a>)<br /><br /><div class="subp">I need to finish extending it to handle <code>YAML</code> and <code>Data::Dump::Streamer.</code></div><br />Term::Throbber (not published anywhere)<br /><br /><div class="subp">I saw <a href="http://search.cpan.org/dist/Term-Spinner/">Term::Spinner</a> and hubris struck me. First I patched Term::Spinner to be able to handle arbitrary sized frames, but then I found my self annoyed by the interface, terminology, and use of vanilla <a href="http://search.cpan.org/dist/Moose/">Moose</a> in Term::Spinner, so I have written my own <a href="http://search.cpan.org/dist/MooseX-Declare/">MooseX::Declare</a> based version. I haven't written any tests for it yet. Once the tests are written and passing (and I am satisfied with the interface) I will put it up on GitHub and CPAN.</div><br />perlopref (<a href="http://github.com/cowens/perlopref">GitHub</a>)<br /><br /><div class="subp">Lots more work needs to be done before this is finished. My goal of adding at least one operator a day failed. I need to recommit myself to getting it done.</div><br />warnin's (<a href="http://github.com/cowens/warnin-s">GitHub</a>)<br /><br /><div class="subp">I think <code>warnin's</code> is going to die an ignoble death. The talk of removing <code>'</code> as a package separator combined with my own apathy means it is unlikely for anything new to be done with it.</div>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-43711614850182852132009-08-16T16:18:00.000-04:002009-08-16T16:19:53.742-04:00project: Anouncing perloprefIn my last post I discussed the need for a <code>perlopref</code> document and even posted a portion of the version I am working on. I got some positive feedback and no negative feedback, so I have created a <a href="http://github.com">GitHub</a> repository and <a href="http://github.com/cowens/perlopref">uploaded what I currently have to it</a>. There has already been <a href="http://github.com/telemachus/perlopref">one fork</a> that fixed some of my POD stupidity.<br /><br />If you want to help, just fork my repository, file <a href="http://github.com/cowens/perlopref/issues">an issue</a> against my repository claiming an operator, make your change, and then submit a pull request. Note: not all of the operators are currently listed in the file (e.g. the filetest operators and the quote-like operators are not yet listed).<br /><br />There is no guarantee that this document will make it into a release of Perl, but at the very least I will be creating a CPAN distribution for it.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com3tag:blogger.com,1999:blog-4206098438326334482.post-38592780065536129022009-08-15T02:34:00.001-04:002009-08-15T02:38:22.873-04:00adventures in ignorance: modulo operatorRecently on the <a href="http://www.perlfoundation.org/perl5/index.cgi?perl_beginners">Perl Beginners mailing list</a> I saw a new user having difficulty <a href="http://www.nntp.perl.org/group/perl.beginners/2009/08/msg108530.html">understanding the documentation</a> for <code>||=</code>. My first reaction was "hey, it is spelled out in straight forward English, <code>||=</code> is like <code>+=</code> but using <code>||</code> instead of <code>+</code>, go look up <code>||</code> and you there you are." Then I starting thinking about it. As a reference, <a href="http://perldoc.perl.org/perlop.html"><code>perlop</code></a> is less than optimal. Many of the operators are discussed tangentially (like ||=) and many others are never mentioned (like the file test operators, which I know are documented in <a href="http://perldoc.perl.org/perlfunc.html"><code>perlfunc</code></a>, but they look like operators to me). This has inspired me to write <code>perlopref</code>. I haven't socialized this anywhere but the Perl Beginners mailing list and here because I want to make sure the idea is viable first. So far it seems to be working for me, and I am learning a lot of the nooks and crannies I had been able to ignore in the past.<br /><br />One of these nooks (or is it a cranny?) is the modulo operator (<code>%</code>), or more specifically what happens with negative numbers. I had never bother to consider how negative numbers would affect modulo. I found the text in perlop to be very opaque. Every time I tried to read it I found my eyes slipping down the page trying to get away, and I know what modulo does. I don't know if it is me, or the text, but I can't imagine trying to understand what the text was saying if I didn't already know what it did. Here is the part that covers modulo in my first draft of <code>perlopref.pod</code> (the pod is available <a href="http://wonkden.net/perlopref-modulo.pod">here</a>)<br /><br /><b>X % Y</b><span style="margin-left: 4em"><br /><u>Description</u><br /><br />This is the modulo operator. It computes the remainder of X divided by Y. The remainder is affect by the type of the numbers and whether they are positive or negative.<br /><br />Given integer operands X and Y: If Y is positive, then <code>X % Y</code> is X minus the largest multiple of Y less than or equal to X. If Y is negative, then <code>X % Y</code> is X minus the smallest multiple of Y that is not less than X (i.e. the result will be less than or equal to zero). To illustrate this, here are the results of modding <code>-9</code> through <code>9</code> with 4:<pre style="margin-left: 2em">when X is -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9<br />the result is 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1</pre>And here is <code>-9</code> through <code>9</code> modded with <code>-4</code>:<pre style="margin-left: 2em">when X is -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9<br />the result is -1 0 -3 -2 -1 0 -3 -2 -1 0 -3 -2 -1 0 -3 -2 -1 0 -3</pre>From this we can see a positive Y constrains X to a range from <code>0</code> to <code>(Y - 1)</code> that wraps around and a negative Y constrains X to a range from <code>(Y + 1)</code> to <code>0</code>.<br /><br />When Y is a floating point number whose absolute value is in the range of <code>0</code> to <code>(UV_MAX + 1)</code> (where UV_MAX is the maximum of the unsigned integer type) X and Y are truncated to integers. If the absolute value of Y is larger than <code>(UV_MAX + 1)</code> then the formula <code>(X - I * Y)</code> (where I is a certain integer that makes the result have the same sign as Y). For example, on 32-bit systems <code>4.5 % (2 ** 32 - 1)</code> is <code>4</code>, but <code>4.5 % 2 ** 32</code> is <code>4.5</code>.<br /><br />Note: when the <a href="http://perldoc.perl.org/integer,html"><code>integer</code></a> pragma is in scope <code>%</code> gives you direct access to the modulo operator as implemented by your C compiler. This operator is not as well defined for negative operands, but it will execute faster.<br /><br /><u>Example</u><pre style="margin-left: 2em">my $odd = $x % 2; #$odd is 1 when $x is odd and 0 when $x is even<br />my $hour = ($hour + 1) % 24; # 23 (11pm) plus 1 hour is 0 (12am).</pre></span>Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com3tag:blogger.com,1999:blog-4206098438326334482.post-70531784386360625922009-08-09T05:38:00.002-04:002009-08-09T05:40:50.083-04:00meta: how I am keeping myself motivated part 2<a href="http://oylenshpeegul.vox.com/">oylenshpeegul</a> asked on my last <a href="http://svok.blogspot.com/2009/08/meta-how-i-am-keeping-myself-motivated.html">meta post</a> about whether or not <a href="http://www.google.com/analytics/">Google Analytics</a> tracks RSS feeds. It does not; however, another Google service does: <a href="http://feedburner.google.com">FeedBurner</a>.<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBXFTvB2XWVy4_IdXOP5kH0Q1zTLDnuaeA6al2EtJbwcVuW4YbE_H0OhCv9RM6DD8DuT6RUdQwr6aqBBRo-3B6J2Uy7FsiedqSMMhL6jeaRN12Wd7dKdJO6nqzJ6OLTxAjOzN_nNvvAe45/s1600-h/feedstats.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 229px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBXFTvB2XWVy4_IdXOP5kH0Q1zTLDnuaeA6al2EtJbwcVuW4YbE_H0OhCv9RM6DD8DuT6RUdQwr6aqBBRo-3B6J2Uy7FsiedqSMMhL6jeaRN12Wd7dKdJO6nqzJ6OLTxAjOzN_nNvvAe45/s400/feedstats.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5367893846145148482" /></a>The data for clicks matches up pretty well against what Analytics is saying. I find the interface to Analytics nicer than FeedBurner, but FeedBurner has statistics about how the feed is being used. I will probably visit both now.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-47120086976135921932009-08-07T23:49:00.002-04:002009-08-08T00:11:10.834-04:00error building Perl 5.10.1-RC1So, if you are trying to compile 5.10.1-RC1 and it throws the error <code>"Can't locate unicore/PVA.pl in @INC"</code>, you most likely have the <code>PERL_UNICODE</code> environment variable set. A quick<pre>unset PERL_UNICODE</pre> will fix the problem (or, at least, it did for me).Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com0tag:blogger.com,1999:blog-4206098438326334482.post-87728115511898805232009-08-07T08:57:00.000-04:002009-08-07T08:58:29.834-04:00meta: how I am keeping myself motivatedSo, I have had blogs in the past, but I have never managed to stay interested in them. This time is different and the reason is simple: data. I turned on Google Analytics and I visit the graphs once or twice a day:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIcWw8RUr7Z_XksLJP0wwrynLy7YIj2SJUh9h8cR_Q2TFtFEaEt3CyqsQkn-YAJ4Hwj30VXBoQHSOtk0lu9WzweLMclKoXOcljoQYuem6LDe9W15PMyamIZks8iRg8zaKbqHLp-fkCTk8k/s1600-h/graph.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 48px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIcWw8RUr7Z_XksLJP0wwrynLy7YIj2SJUh9h8cR_Q2TFtFEaEt3CyqsQkn-YAJ4Hwj30VXBoQHSOtk0lu9WzweLMclKoXOcljoQYuem6LDe9W15PMyamIZks8iRg8zaKbqHLp-fkCTk8k/s400/graph.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5367201929092780786" /></a>Just this little reassurance that people are looking at what I am writing is keeping the blog in my mind. Because it is in my mind, when something happens (like, say, my next article about my stupidity using <a href="http://perldoc.perl.org/functions/split.html"><code>split</code></a> and <a href="http://perldoc.perl.org/functions/ord.html"><code>ord</code></a>) I remember to start writing stuff down.Chas. Owenshttp://www.blogger.com/profile/11716389363199045015noreply@blogger.com6