If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User Meditations
Persuading turkeys to vote for christmas
6 direct replies — Read more / Contribute
by BrowserUk
on May 19, 2016 at 19:44

    Tipping is a culturally dividing phenomena.

    In some parts of this world, paying some optional (but expected), discretionary (but socially narrowly defined) percentage of the bill for your food, to the house, for them to divvy up according to some (usually wholly inequitable) formula, between everyone front of house (and sometimes those in the back) -- often including those you feel do not warrant a tip -- in lieu of paying them a descent wage; is the $NORM.

    In other parts; tipping is a genuinely discretionary gratuity, paid by you to that or those persons you feel are deserving of it.

    The weird part is that most everyone in those former parts can see the inequities; but they blithely continue to perpetuate them anyway.

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Mocking isa under Test::Deep
1 direct reply — Read more / Contribute
by choroba
on May 01, 2016 at 16:01
    At work, we use a rather old Perl on the servers (5.10.1 on RedHat 6, but still better than 5.8.3 at my $job-1), with similarly dated distributions. We plan to upgrade, so I tried running some of the tests locally on my laptop with Perl 5.18.2 (openSUSE Leap 42.1).

    Hash randomisation

    Most failures were caused by the new hash randomisation (see Hash order randomization is coming, are you ready?). As we use Test::Spec, most failures can be solved easily by turning an array reference into a bag:

    # Old: cmp_deeply($obj->method, [ $result1, $result2 ]); # New: cmp_deeply($obj->method, bag($result1, $result2));

    Mocking objects under Moose

    We use Moose in most of the code, which makes mocking a bit harder because of type constraints. Imagine you have the following code you need to test:

    use warnings; use strict; { package Person; use Moose; use namespace::autoclean; has name => ( is => 'rw', isa => 'Str', required => 1, ); has id => ( is => 'ro', isa => 'Str', required => 1, ); __PACKAGE__->meta->make_immutable; } { package Position; use Moose; use namespace::autoclean; has person => ( is => 'rw', isa => 'Person', ); has title => ( is => 'ro', isa => 'Str', ); __PACKAGE__->meta->make_immutable; }

    When testing the Position, we don't care about the details of the Person. We only want to stub an object with the needed methods implemented, which can even be none:

    use Test::Spec; describe 'position' => sub { it 'instantiates' => sub { my $person = stub(); my $position = 'Position'->new(person => $person); isa_ok($position, 'Position'); cmp_deeply([ $position->person ], bag($person)); }; };

    (The last line doesn't make much sense in this context, but imagine more complex objects. We need to use the bag function somewhere to show the problem.)

    This would work under plain OO, but it doesn't for us; Moose complains:

    Attribute (person) does not pass the type constraint because: Validati +on failed for 'Person' with value Test::Spec::Mocks::MockObject={ }

    The common trick to solve this, appearing all over the code base, has been to stub the isa method of the object to always return 1. Moose's got happy when checking the object type, and no one else has cared:

    my $person = stub( isa => 1 );

    But alas, this trick doesn't work in the newer Test::Deep. Here's the failure message:

    Found a special comparison in $data You can only use specials in the expects structure at /home/choroba/pe +rl5/lib/perl5/Test/Deep.pm line 346.

    Pretty informative, don't you think? It took me several hours to find the exact reason; the indicated line was changed in May 2011 in the following way:

    # Old: if (! $Expects and ref($d1) and UNIVERSAL::isa($d1, "Test::Deep::Cmp") +) # New: if (! $Expects and Scalar::Util::blessed($d1) and $d1->isa("Test::Deep +::Cmp"))

    So, returning 1 from the isa method now makes Test::Deep believe the stubbed object is its special construct that shouldn't appear on the left hand side of the comparison.

    To verify that's actually the problem, I tried to modify the isa in a more sophisticated way:

    my $person = stub( isa => sub { $_[1] !~ /Test/ } );

    and yes, it started to work again. Moose asks for Person , so isa returns 1, the testing framework asks for Test::Deep::Cmp and therefore gets 0.

    Final solution

    But it's an ugly hack. Some other modules might get confused by such a mocking, as they might check for other classes not containing Test , or, worse, we also have several classes whose namespace contains Test somewhere. So, I created a helper function

    sub mock_isa { my ($class) = @_; isa => sub { $_[1] eq $class } }

    which can be used as

    my $person = stub(mock_isa('Person'));

    Not as short as the original trick, but still easier than reimplementing the whole inheritance logic. What tricks do you use?

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Reversed .= operator
4 direct replies — Read more / Contribute
by 1nickt
on Apr 29, 2016 at 12:40

    Hi all,

    I'm sure we've all wished for a concatenation operator that would prepend a string to a string in the same way the .= operator appends.

    So why isn't there one?

    It's silly that you can write:

    $foo .= 'bar';
    But not:
    $baz =. 'qux';
    and instead have to do:
    $baz = 'qux' . $baz;

    Today I got to wondering if I had missed that such an operator had been introduced in some recent Perl version so I ran the code, and to my surprise Perl said:

    Reversed .= operator at -e line 5. syntax error at -e line 5, near "=."
    Now, if Perl knows that this particular syntax error is a "reversed .= operator", and not, say, "some new operator I didn't know about" - i.e. the syntax is not in use for anything else - then why isn't it implemented?

    Can any guts gurus shed any light?

    The way forward always starts with a minimal test.
Regular Expreso 2
2 direct replies — Read more / Contribute
by choroba
on Apr 26, 2016 at 16:24
    As you might have noticed, I like programming puzzles and brain teasers. But I hadn't participated in a real public contest... until today. I registered to Regular Expreso 2 on HackerRank. The participants had 24 hours to solve 8 tasks, Perl was among the supported languages. The contest was regular expression-centered, your code had to always end the same:
    $Test_String = <STDIN> ; if($Test_String =~ /$Regex_Pattern/){ print "true"; } else { print "false"; }

    The top 10 contestants (most points + shortest time) won a T-shirt. Once I realised there were more then 10 people with the full score, I knew I wasn't getting one, but I still wanted to get the full score.

    But I had no idea how to solve one of the tasks: the input was a long string of zeroes and ones. Your regex had to recognise whether the string encoded two binary numbers in the following way: when you reversed the string and extracted the odd digits, you got a number three times greater than the one built from the remaining digits. For example,

    1110110001 => 00111, 10101 7 21 3 * 7 = 21, accept!

    I wrote a short script to generate some examples, but I wasn't able to find the pattern. Moreover, the regex couldn't have more than 40 characters!

    Then I remembered Perl has a way to run code in a regex: the (?{...}) pattern. I read the relevant perlre section several times and tried something like the following:

    use bigint; sub check { my ($bin, $three) = ('0b') x 2; my $s = $_; while ($s) { $three .= chop $s; $bin .= chop $s; } return oct $three == 3 * oct $bin } $Regex_Pattern = qr/(?{ check() })/;

    The problem here is that (?{...}) always matches. Fortunately, you can use the code pattern as the condition in


    As the yes-pattern, I used ^ which always matches, and (*FAIL) for the no-pattern:

    $Regex_Pattern = qr/^(?(?{ check() }) ^ | (*FAIL) )/x;

    The qr adds some characters, so to be sure I don't overflow, I renamed the subroutine to c and golfed the solution to


    I got the full score! Would you call such a solution cheating? On one hand, I see that's not what the organisers wanted me to do, on the other hand, that's what Perl regular expressions give you. In fact, with the "start or fail" pattern, I can solve almost any problem with a regular expression!

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Good practice: A case for qr//
1 direct reply — Read more / Contribute
by LanX
on Apr 25, 2016 at 13:28
    Just wanted to share why using qr// to store regexes is usually a better idea than using strings...

    Today I was told to debug why a night batch failed to complete in the last weeks ...

    As it turned out filenames where checked with a list of hardcoded regexes and one of them had a typo. Instead of filter => ".*pl|.*txt" it had ".*pl|*.txt" which was hard to spot among many other regexes and caused a runtime error.

    Now using qr would have caused filter => qr/.*pl|*.txt/ to fail immediately at compile time.

    And since my colleagues use Komodo which runs perl -c at background (aka flymake-mode in emacs) this would have meant noticing the typo instantly while editing.


    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

    PS: not wanna talk about the other flaws, like why extensions are checked with handcrafted regexes or why exitcodes from batches weren't checked...

Bullish on Moose, how about you?
7 direct replies — Read more / Contribute
by nysus
on Apr 22, 2016 at 16:44

    I've been a programming dabbler on an off for the past sixteen years or so (not counting the year I learned Apple Basic as a kid). I've recently gotten heavily back into programming for a couple of largish personal projects; most recently a event aggregator for the community where I live. For the last project, I decided to take a stab at doing OO Perl because too often I found that my procedural code for larger projects often degraded into spaghetti code as I dropped in more and more code to address all the edge cases that inevitably cropped up.

    Fortunately, I had worked some with "old school" OO Perl in the past, just to get familiar with it. I had also played a little with other OO-oriented languages so was pretty familiar with most of the concepts. Still, I had to dig out my worn copy Damian Conway's "Object Oriented Perl" book written back in 2000 to refresh myself. But after writing a fairly modest program with old school OO Perl, it became apparent that it's probably not practical for a less experienced programmer like me to use old school OO Perl for bigger, more complex projects like the event aggregator I was trying to build. I had to waste too much effort worrying about whether I was using Perl properly to implement OO design and grok all kinds of advanced programming techniques to make it all work.

    Then some Monks here recommended that I try Moose. I had never heard of Moose but, man, I am extremely glad I took their advice. Over the past month or so that I have been working with Moose, I found it to take a lot of the tedium out of programming and it has made it a much more joyful and less frustrating experience for me. When I see my code taking on the form of stringified pasta, I can easily break the code down into discrete chunks that makes it much easier for me to focus on the big picture of the program's structure and less on the detailed ins and outs of what the code is doing. I have a lot left to learn with Moose but there seems to be little question at this point in time that Moose will make me a better, more productive programmer and will help me create much more maintainable code. I can't see myself using anything but Moose for all but the simplest of scripts.

    I'm wondering if other Monks who have tried Moose have similar feelings as me. Maybe I was just horrible procedural programmer. Have you tried Moose and then abandoned it? Right now I don't see any downsides to using it (my scripts don't have to run fast), but I'd be interested to know if you have a different take on Moose. Are there any limitations inherent to Moose that I should be aware of?

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks

Support for URLs with link titles in Pod::Html
1 direct reply — Read more / Contribute
by thomas895
on Apr 19, 2016 at 01:03

    Pod::Html, which ships with the core, breaks on things like


    ...with an error message like

    C:\STRAWB~1\perl\bin/pod2html.bat: ../test.pod: cannot resolve L<PerlM +onks|http://www.perlmonks.org/> in paragraph 6.

    This is not unique or new, as evidenced by hyperlinks in pod and others.

    I still use 5.12.3 (too lazy to reinstall all the modules I've accumulated), so I decided to patch the module so it does accept the URLs by putting together two other expressions.
    In v1.09 (the latest version of its kind), around line 1605, add this snippet after the if block:

    # some L<>'s that shouldn't be: # a) full-blown URL's are emitted as-is if( $par =~ m{^\w+://}s ){ return make_URL_href( $par ); } # --- add this: --- elsif( $par =~ m{^([^|]+)\|(\w+)://(.+)}s ) { #link text in $1, scheme in $2, everything else in $3 return sprintf '<a href="%s://%s">%s</a>', $2, $3, html_escape($1) +; }

    It might not work in all cases, but it seems to work for everything I could think of.

    Pod::Html was replaced with a Pod::Simple solution in v5.16.0 (as evidenced by perl5160delta), but if you use something older like I do, and you've run into this frustration, it might save you the bother of having to rewrite a bunch of code to use something else.

    Bonus: Make the output more XHTML compliant

    The output may say that it's XHTML-1.0 compliant, but this is not the case. One example that bothers XML parsers is that the <dt> tags aren't closed all the time. For example, when you have...

    =over 1 =item bla asdfghjk =back

    ... the resulting dt is closed as you would expect. But when you have...

    =over 1 =item sdfsfgsdh =back

    ...it just outputs a blank, unclosed dt tag (followed by a dd tag with the text in it, as expected). To fix this, change this part around line 1211:

    if ($text =~ /\A(.+)\Z/s ){ # should have text emit_item_tag( $otext, $text, 1 ); # write the definition term and close <dt> tag print HTML "</dt>\n"; }

    to this:

    if ($text =~ /\A(.+)\Z/s ){ # should have text emit_item_tag( $otext, $text, 1 ); } # write the definition term and close <dt> tag print HTML "</dt>\n";
    "Excuse me for butting in, but I'm interrupt-driven..."
developing in vim and tmux
4 direct replies — Read more / Contribute
by morgon
on Apr 17, 2016 at 19:09
    Sorry for slightly misusing this section as this is not something deep - just a little productivity hack...

    As a vim-user for many years I would edit my script in the one true editor and then run it (again and again for development) either in another terminal altogether or would background vim via Ctrl-Z.

    But now I have found something more convenient.

    If you run vim inside tmux and install the vimux-plugin you can send tmux-commands from within vim.

    Now add this to your .vimrc:

    let mapleader=" " map <Leader><space> :VimuxRunCommand("perl " . bufname('%'))
    If you now open your perl-script in vim within a tmux-session and hit <space> twice (tweak the key-binding to your liking), a new tmux-pane opens and runs your script - without loosing focus in vim - so much nicer...
When does programming become automatic (if ever)?
15 direct replies — Read more / Contribute
by nysus
on Apr 12, 2016 at 18:56

    We have all seen gifted programmers who seem to have an innate ability to code circles around others. These coders are like the 12 year old prodigies you see banging out Scott Joplin tunes on the piano like nothing. I'm sure there are many Monks blessed with this kind of skill.

    But leaving the gifted ones aside, how long does it take for the "normal" person to code fluently? By "fluently" I mean being able to code about as effortlessly as one types out prose in their native language into the keyboard. It means not having to think about the mundanities of grammar or spelling or syntax. Instead, you just let the ideas in your head flow kind of magically out from your brain and into your fingertips. It also means you know a lot of the basic tropes and idioms to express yourself in a clear, compact way without much effort. Maybe every once in a while you consult a dictionary or thesaurus but by and large you can bang out something relatively quickly without much struggle.

    As a programming hobbyist who has never worked alongside other programmers, I'm curious to know if this state is achieved by most professional programmers and what it takes to get there. Are we looking at 2 years of full-time programming? 5 years? 10? Or maybe programming is by nature an activity that starts and stops in fits and is never quite effortless? I'd be interested in hearing some experienced programmer's thoughts on this and what it took to get you to a blissful, effortless state of coding.

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks

To assume network or not
3 direct replies — Read more / Contribute
by stevieb
on Apr 11, 2016 at 18:51

    I've created a module that at first, was designed to be standalone. Since, I've updated it to make it network-capable, and it now, in one specific mode, acts as a distribution centre, commanding other systems to perform the tasks and return the results. The standard mode of single-system is still available

    I've found that now I have to manage the results from the local instance a lot differently than the remote results, so I'm effectively doing a lot of duplicate work.

    My options are: maintain the project and handle both the local results and the network results seamlessly, fork out the module and spin off a ::Standalone version that functions like the pre-network version, or assume by default that at minimum, localhost traffic will always work, and have the local procedures work over a network call to a localhost listener, even if the user doesn't want to ever use the distribution aspect of the dist.

    What are your thoughts on this? Is it ok to assume at minimum local (ie. localhost) network comms in today's world, or would you take one of the other approaches (or even one I haven't considered)?

[OT] A prediction.
8 direct replies — Read more / Contribute
by BrowserUk
on Apr 06, 2016 at 22:32

    The speed of light is not constant!
    It is, in fact, accelerating, year by year, decade by decade, century by century; but on astronomical time-scales.

    It may take ten years; it make take one hundred. Or even a thousand.

    But, it will eventually be proved that the speed of light is not a constant. (And this has nothing to do with frames of reference; or General, or Special Relativity.)

    If you set up a series of light beams, every cm(inch) across a road, 1 km(mile) long; and measured the (instantaneous) speed of a car starting from standstill and accelerating along that road to 100k(m)ph; and then viewed the data from the last 100cm(inches); it would appear (within the bounds of accuracy available) that the speed of the car was some fixed(constant) value.

    Now consider that we (human kind) have only been attempting to measure the speed of light for 300 or 400 years -- depending upon your references -- and that light has been traveling for ~13.something billion years(*); and maybe the above analogy will make sense.

    Now think about the consequences, if that is true.

    Distances -- and thus times -- of astronomical points and events -- including the age of the Universe/time since the big bang -- are no longer reliable.

    The calculations that "prove" that the Universe is expanding and will continue to expand until heat death; are unreliable. Unproven.

    The mass calculations that indicate the existence of both Dark Matter and Dark Energy are moot.

    The vast majority of current astrophysical and particle physical research are looking in the wrong place, for the wrong thing.

    Wanna join the 21st Century's version of the flat Earth society?

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Raspberry Pi and Perl
3 direct replies — Read more / Contribute
by marinersk
on Apr 06, 2016 at 01:33

    I'm finally entering into the world of prototype robotics. The research has been fun, even fascinating at times, but I'm at a point where getting feedback from those whose opinions I respect seems appropriate.

    I'm looking for general feedback from any Monks who have worked in that space on the values or detriments of using Perl on Raspberry Pi in this capacity.

    For a variety of reasons, I'm leaning toward using as close as possible to stock builds. A good argument for a different Linux or a different Perl is welcome, of course.

    Arguments for the Windows OS on Raspberry are also welcome, I suppose, but the argument will likely be challenged to pique my interest for long.

Philosophy for when not to support older versions of perl
6 direct replies — Read more / Contribute
by stevieb
on Mar 29, 2016 at 19:24

    As far as I recall, all of my modules will work going back to 5.8 and previous, but I'm looking for opinions for cutoff lines... ie. what is it that makes you determine when not to support older versions?

    I recently came into an issue that will force me to write three extra lines to be v5.8 compatible vs v5.10, which got me wondering how much work others will do before bumping the minimum version of perl (I'm sure requiring a module that you didn't write that uses newer features is likely a big one. Any others?).

What if someone liberated his Perl modules?
3 direct replies — Read more / Contribute
by perlancar
on Mar 23, 2016 at 04:57

    There is a recent event where a Node.js developer decided to unpublish all of his 250 or so modules on npmjs.org (including some very popular modules, causing large breakage) following a corporate takedown notice for one of his modules. The ensuing HN discussion thread highlights a security issue where a malicious author could upload a malicious update to a previously existing (but then unpublished) module. I'm wondering how such issue is handled in the Perl (CPAN) community.

    If someone unpublishes his module (i.e. deletes the release tarball from PAUSE), at least there's an extra step where he must also give up his primary maintainer/co-maintainer status to allow others to upload to the same package name. Well, that's not entirely correct. PAUSE allows any author to upload distribution which contains modules that occupy the same namespace as existing ones, it's just that the modules won't be indexed if the version number is older than existing indexed one or if there is insufficient permission. But once the original author makes the namespace available again, it's back to free for all: any other PAUSE author (malicious or not) can theoretically upload to the same namespace and spread malware or compromise users' systems via module update. It's easy to register a PAUSE account.

    PAUSE creates a CHECKSUMS file in author's directory, listing each release file along with its last modified time, size, MD5 and SHA256 checksums. The CHECKSUMS file is then signed by PAUSE. A CPAN client can be instructed (e.g. --verify in cpanm) to check the signature of the CHECKSUMS file.

    A couple of issues: 1) signature verification is not enabled by default in CPAN client (at least in cpanm); 2) most (all?) CPAN mirrors are ftp/http and not https, so during the first installation where the client does not have PAUSE's public key yet, a MITM attack can spoof the CHECKSUMS file as well as the release tarballs without the client being able to detect it. These issues can be fixed in the client: enable --verify by default and bundle the PAUSE public key.

    Additionally, an author can also sign his distribution using a framework like Module::Signature. This will create a SIGNATURE file in the top-level directory of the distribution which contains the checksums of the files in the distribution. The SIGNATURE is then signed using the author's PGP key. This protects the distribution from being tampered by the server (in this case, PAUSE).

    A CPAN client can then be instructed (also --verify in cpanm) to check this signature file. The 'cpansign' CLI tool distributed along with Module::Signature can also be used for this purpose. The same issue also exists: verify is not enabled by default. And another issue, code signing by author is not mandatory and as far as I know, only a small percentage of authors do this. And yet another issue, at least when I tried it, tool like 'cpansign' is not strict by default: when it fails to retrieve the required PGP public key, it stills reports "==> Signature verified OK! <=".

    A more paranoid CPAN client can also be setup to only accept a predefined set of authors' keys. This can mitigate the issue of another previously unknown PAUSE author trying to push an update to existing module.

    Client system can also protect against regular update breakage by setting up a private DarkPAN repository where each module update is first tested then pushed to this repository. Client machines then update their Perl modules from this private repository and not directly from a CPAN mirror.

    Conclusion: there are mechanisms already in place in the CPAN infrastructure to prevent the abovementioned security issue. But the problem is they are not enabled by default.

Re: Is there a place on PM outlining community policy
1 direct reply — Read more / Contribute
by stevieb
on Mar 23, 2016 at 01:43

    My rules:

    • act as I want to be treated
    • acknowledge and apologize when I've been an unwarranted asshole
    • when sharing information or giving advice, be as diligent as possible
    • always, and I mean *always* give credit where it is due
    • be honest; being a phony gets you nowhere
    • call it on people when they are wrong, while at the same time, be able to acknowledge when you were
    • stay out of bikeshed conversations, unless you're willing and able to discuss the larger scenarios
    • don't pout if you've been showed-up; research and learn from it
    • realize everyone makes mistakes... it's ok to question anyone's opinion
    • give back more than you take


Add your Meditation
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.